VBAでJITから文字出力するため、Debug.Printのラッパーを定義してコールバックさせてみました。ラッパーのアドレスを引数で渡しています。
簡単に見えますが、結構ハマりました。
- pushでespがずれたのを忘れて[esp+8]で引数を取ろうとした。
- PutCharの引数にByValを付け忘れた。ポインタ渡しと認識されるため、[65]にアクセスしようとして落ちた。
Brainf*ckをJITで動かすのに使えないかと思い実験してみました。
【お知らせ】プログラミング記事の投稿はQiitaに移行しました。
対話的にAPIで遊べるのは面白いです。しかしちょっと間違えるとExcelごと落ちてしまうため、かなり危険な遊びです。もし対話的にネイティブを取り扱う環境を作るなら、他のプロセスをデバッグするのが良いかも、というようなことを妄想しました。
それにしてもBASICからマシン語を呼び出すなんて、なんて懐かしいことをやっているのでしょう!
以前、Deflateの圧縮アルゴリズムを変えながらヒッパルコス星表の圧縮時間を計測しました。
最低圧縮率の方式はVBAへの移植を考えて実装しました。そこで今回、実際にVBAに移植しました。結論から言うとインタプリタ方式のVBAは、JIT方式のF#の25倍ほど遅かったです。
今回計測に使用したコードは以下にあります。
まだ改善の余地があると感じたため、以下の手順でチューニングを試みました。
処理速度は倍程度に向上しています。(単位:秒)
以下の言語に移植しました。
処理速度を計測しました。Visual Studio系は2010のExpress Editionです。g++のReleaseは-O3、Debugは-O0です。比較対象として.NET Framework標準のDeflateStreamも計測しました。(単位:秒)
.NET言語同士だとあまり違いはありませんでしたが、ネイティブのC++は速かったです。Andromedaという独自言語もネイティブではあるのですが、最適化がまったくない上、出力するコードの効率も悪く、最適化しないC++の3倍近くも遅いという結果になりました。