Created
April 13, 2019 02:29
-
-
Save gcolvin/b2b1198b4c95e3518c93e7ab048d7572 to your computer and use it in GitHub Desktop.
minimal function vs switch interpreter comparison
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdlib.h> | |
#include <string.h> | |
#include <time.h> | |
#include <stdio.h> | |
namespace interp { | |
enum ops { STOP, ADD, SUB, MUL, DIV }; | |
const char* op_stop(long*&,const char* PC) { | |
return PC; | |
} | |
const char* op_add(long*& SP,const char* PC) { | |
SP[-2] += SP[-1]; | |
--SP; | |
return ++PC; | |
} | |
const char* op_sub(long*& SP,const char* PC) { | |
SP[-2] -= SP[-1]; | |
--SP; | |
return ++PC; | |
} | |
const char* op_mul(long*& SP,const char* PC) { | |
SP[-2] *= SP[-1]; | |
--SP; | |
return ++PC; | |
} | |
const char* op_div(long*& SP,const char* PC) { | |
SP[-2] /= SP[-1]; | |
--SP; | |
return ++PC; | |
} | |
typedef const char* (*op)(long*&, const char*); | |
static const op ops[5] = { | |
&op_stop, &op_add, &op_sub, &op_mul, &op_div | |
}; | |
struct funterp { | |
long stack[1024]; | |
long* SP = 0; | |
const char* PC = 0; | |
void exec(char* code) { | |
SP = stack + sizeof(stack)/sizeof(long); | |
PC = code; | |
while (*PC) { | |
PC = ops[*PC](SP, PC); | |
} | |
} | |
}; | |
struct switerp { | |
long stack[1024]; | |
long* SP = 0; | |
const char* PC = 0; | |
void exec(char* code) { | |
SP = stack + sizeof(stack)/sizeof(long); | |
PC = code; | |
for (;;) { | |
switch (*PC) { | |
case STOP: | |
return; | |
case ADD: | |
SP[-2] += SP[-1]; | |
--SP; | |
++PC; | |
break; | |
case SUB: | |
SP[-2] -= SP[-1]; | |
--SP; | |
++PC; | |
break; | |
case MUL: | |
SP[-2] *= SP[-1]; | |
--SP; | |
++PC; | |
break; | |
case DIV: | |
SP[-2] /= SP[-1]; | |
--SP; | |
++PC; | |
break; | |
} | |
} | |
} | |
}; | |
} | |
int main() | |
{ | |
const int N_TEST = 100000; | |
interp::funterp testfuncs; | |
interp::switerp testswitch; | |
long stack[1024]; | |
for (int i=0; i < 1024; ++i) | |
stack[i] = random(); | |
char program[513]; | |
for (int i=0; i < 512; ++i) | |
program[i] = random()%3 + 1; | |
program[512] = interp::STOP; | |
long now, then; | |
now = then = clock(); | |
for (int j=0; j < N_TEST; ++j) { | |
memcpy(testfuncs.stack, stack, sizeof stack); | |
testfuncs.exec(program); | |
} | |
now = clock(); | |
printf("functions: %ld\n", now - then); | |
now = then = clock(); | |
for (int j=0; j < N_TEST; ++j) { | |
memcpy(testswitch.stack, stack, sizeof stack); | |
testswitch.exec(program); | |
} | |
now = clock(); | |
printf("switch: %ld\n", now - then); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment