2 ms·
It's worth looking at the C code that's generated from a simple blink example in haskell. It's not very idiomatic, but neither is it very slow. Much of the fluf
by joeyh 7y ago
It's worth looking at the C code that's generated from a simple blink example in haskell. It's not very idiomatic, but neither is it very slow. Much of the fluff should get optimised away by the C compiler. I've been generally very impressed with how readable the output is, as generated code goes, and how performant it seems.
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
static bool s0[(2)] = {(false), (true)};
static size_t s0_idx = (0);
bool s0_gen(void) {
return (s0)[s0_idx];
}
bool delay_guard(void) {
return true;
}
int16_t delay_arg0(void) {
return 100;
}
bool digitalWrite_guard(void) {
return true;
}
int16_t digitalWrite_arg0(void) {
return 13;
}
bool digitalWrite_arg1(void) {
return (s0)[s0_idx];
}
void step(void) {
if ((delay_guard)()) {
(delay)(((delay_arg0)()));
};
if ((digitalWrite_guard)()) {
(digitalWrite)(((digitalWrite_arg0)()), ((digitalWrite_arg1)()));
};
((s0)[s0_idx]) = ((s0_gen)());
(s0_idx) = ((++(s0_idx)) % (2));
}
void setup()
{
pinMode(13, OUTPUT);
}
void loop()
{
step();
}
- joeyh 7y agoDoing some constant folding, the C compiler would arrive at something like this: void loop(void) { delay(100); digitalWrite(13, s0[s0_idx]); s0[s0_idx] = s0[s0_idx]; s0_idx = (++s0_idx) % 2; } void setup() { pinMode(13, OUTPUT); } Only the s0[s0_idx] = s0[s0_idx] looks like extra work now. I don't know if a C compiler would optimise that away, but assuming it does not, one extra memory write per loop is not bad overhead.