四則演算、スタックマシンのベンチマーク
O i Oi r rO ri riO 元 : 570 460 381 361 360 350 311 310 読込 : 571 531 370 360 361 371 320 340 最適化 : 371 310 380 321 290 260 291 260 関数化 : 461 381 370 320 311 300 290 261 動的 : 120 err 110 err 350 err 350 err 動的ASM : 30 err 20 err 30 err 30 err 動的読込 : 110 err 120 err 360 err 60 err トランス : 101 80 90 70 70 60 70 60 トランスASM: 30 20 41 30 30 30 30 30
とってみました。
トランスレータ速いですねぇ。
さらに、CPUのスタックを使ってやると速いってことがわかりました。
動的というか、実行時コンパイルは、最適化かけるとエラーでます。
で、なんだっけ、、、
ActionScript3.0にコンパイルするには、トランスレータ書けば十分じゃないのかという
ざっとした、結論が得られました。
てことは、6502のアセンブラ作るって話になるのか。。。
というか、NESの開発環境を作ることになるのか。
できるのかよ!
; ; スタックマシン用プログラム ; PUSHI 1 PUSHI 2 ADD PUSHI 10 MUL PUSHI 1 SUB PRINTI RET
これを読み込んで、Dのソースを出力する。トランスレータ
import std.string; import std.file; int main(char argv) { // ファイル読み込み char str = cast(char)read(argv[1]); // トランスレート printf("enum { MAX_STACK = 200 };\n"); printf("int stack[MAX_STACK];\n"); printf("int sp = MAX_STACK - 1;\n"); printf("int main() {\n"); foreach (char line; str.split("\n")) { char[] c = line.split(); if (c.length == 0) continue; switch (c[0]) { case "POP": printf("\t++sp;\n"); break; case "PUSHI": printf("\tstack[sp--] = %.*s;\n", c[1]); break; case "ADD": printf("\tstack[sp+2] = stack[sp+2] + stack[sp+1]; ++sp;\n"); break; case "SUB": printf("\tstack[sp+2] = stack[sp+2] - stack[sp+1]; ++sp;\n"); break; case "MUL": printf("\tstack[sp+2] = stack[sp+2] * stack[sp+1]; ++sp;\n"); break; case "PRINTI": printf("\tstack[sp+1] = printf(\"%%d\\n\", stack[sp+1]);\n"); break; case "RET": break; default: break; } } printf("\treturn 0;\n"); printf("}\n"); return 0; }
で、出力結果。
enum { MAX_STACK = 200 }; int stack[MAX_STACK]; int sp = MAX_STACK - 1; int main() { stack[sp--] = 1; stack[sp--] = 2; stack[sp+2] = stack[sp+2] + stack[sp+1]; ++sp; stack[sp--] = 10; stack[sp+2] = stack[sp+2] * stack[sp+1]; ++sp; stack[sp--] = 1; stack[sp+2] = stack[sp+2] - stack[sp+1]; ++sp; stack[sp+1] = printf("%d\n", stack[sp+1]); return 0; }
分岐とか考えると、もうちょっと複雑になりますが、まぁ、こんくらいで。