Bjam

optional_iteratorの除去

逆アセンブルリストを比較しているとインライン化の妨げになっているようだったので、optional_iteratorを使わないようにしました。 差分 COWベースのstring_list(注:名前はlistだけど実体はvector)で、リストが空でvectorが作成されていない状態のbegin()/e…

BOOST_SPIRIT_USE_LIST_FOR_TREES

マクロBOOST_SPIRIT_USE_LIST_FOR_TREESを定義した場合にコンパイルできない問題だけ修正しました。 差分 通常、Boost.Spiritの構文木は、 template<class T> struct tree_node { typedef std::vector<tree_node<T> > children_t; T value; children_t children; }; のような構造体</tree_node<t></class>…

パースエラー

今日は全然縮まなかったので、以前デバッグ中に見つけたクラッシュするパターンを調査しました。 原因はデバッガで覗くとすぐに判明。include文で読み込んだjamファイルのパースが成功したかどうかチェックしていないだけでした。 とりあえず適当な例外を投…

Re: bjam高速化 その5

string_listの要素アクセスで、 const std::string& string_list::operator[](size_type n) const { if (n < size()) return (*pimpl_)[n]; else return dummy; } みたいなことをしていると勘違いして、ループ内部でアクセスする場合にサイズチェックが無駄…

bjam高速化 その8

今日も測定に時間がかかってあまり進んでません。 ローカル変数は「値の設定時に古い値を取っておいて、後で元に戻す」ことで実装しているのですが、元に戻す際にmapを探索するのが無駄なのでポインタを覚えて置くようにしました。 差分 実行時間はこうなり…

bjam高速化 その7

TICKを仕込む範囲を狭めていって、コードを調べていたところ、変数の展開処理に明らかな無駄があったので修正しました。 差分 jam言語の変数展開では修飾子によって変数の値を加工できるため、変数展開の度に文字列リストを生成していたのですが、 X = $(HOG…

bjam高速化 その6

Hamigaki.Bjamでは組み込みルールを自分で追加できるので、これを使ってjamファイルの計測をしてみました。 namespace bjam = hamigaki::bjam2; bjam::string_list tick(bjam::context& ctx) { std::cout << ::GetTickCount() << std::endl; return bjam::st…

bjam高速化 その5

今日は単純なループの手抜きを直しました。 差分 for (std::size_t i = 0; i < vec.size(); ++i) ... を for (std::size_t i = 0, size = vec.size(); i < size; ++i) ... に変えただけです。 「STLアルゴリズムを使え!」という感じですが、途中で抜ける条…

bjam高速化 その4

文字列キャッシュを作ろうと思ったんですけど、bjamのソースを見るとBoost.Flyweight同様に一旦文字列をコピーしているようで、あまり効果がないかもしれず取りやめました。 結局、今日はほんの少ししか改善できませんでした。 差分 う〜ん、後は片っ端から…

bjam高速化 その3

文字列をキャッシュしてどれくらい速くなるかのテストとして、文字列リスト(hamigaki::bjam2::string_list)の要素をBoost.Flyweightに差し替えてみました。(参考: wikipedia:Flyweight パターン) まだSVN trunkにコミットされていない キャッシュは静的変数…

bjam高速化 その2

今日もいくつか変更を加えたんですが、実行時間は誤差程度しか変化ありませんでした。 プロファイリングの上位にある関数に手を加えてもあまり変わらないということは、ボトルネックの部分がインライン化されて多くの関数に分散しているということかもしれま…

bjam高速化 その1

Windows版もSolaris版の速度に近づいてきたので、今日はSolarisでのプロファイリング結果を参考にしながら高速化していました。 skip_parserをruleを使わない独自実装に置き換えた expand_variable()で直積を作る必要がない場合に関数を中断するように変更 t…

_SECURE_SCL

VC++用のまともなプロファイラが手元にないので、結果に影響ない範囲で同じ関数を二度呼ぶ手法で所要時間の概算を調査しています。 例えばnew/deleteの時間を測るには、 #include <new> #include <cstdlib> void* operator new(std::size_t size) throw(std::bad_alloc) { </cstdlib></new>…

file_status_cache

boost::filesystem::statusとディレクトリリストをキャッシュするfile_status_cacheを実装してみました。 今日の差分 このキャッシュは期限も容量制限もなく、単に蓄積されます。 更新時間のチェックもしていないので、bjam実行中に追加や削除が行われても反…

プロファイリングしてみた

ぱっと見で速くなりそうなところを直したところで、Solarisでプロファイリングしてみました。 Linuxを使わなかったのは、プロファイリング用にビルドされたバイナリがFedoraのパッケージにはなさそうだったからで、Solaris(Nexenta)ではソースからビルドする…

no_node_d

プロファイルを取るまでもなく、明らかに速くなりそうだったので、Boost.Spiritのno_node_dディレクティブを使って、構文木から余分なノードを削除してみました。 差分 ver 時間 v1 87.500秒 v2 70.734秒 no_node_d 56.609秒 結構減りました。 この調子なら…

構文木を作る その10

ようやくテストをパスしました。 差分 さて、速度比較のためbjam_dumpを実行してみたのですが、これがなかなか動きませんでした。 これはテストケースをもっと増やさないとダメですね。 一部、仕様(というかbjamのソース)を読み違えていたところもあって、こ…

構文木を作る その9

構文木を評価するevaluate_bjam()を作りました。 差分 実装は昨日まで使っていたテストプログラムの流用です。 これでパーサーと(狭義の)インタプリタの実装が終わったので、残りのコンポーネントも旧バージョンからコピーしてきました。 差分 現在、テスト…

構文木を作る その8

えー、昨日のエントリはなしで、、、。 matchのvalueとnode_val_dataのvalueがごっちゃになってました。 結局、Boost.Spiritの構文木の枠組みに合わせて、独自の実装を作成しました。 parse_tree.hpp parse_tree.hpp まず、node_val_dataは反復子に依存する…

構文木を作る その7

昨日の考察で結論がでたはずだったんですが、構文木に反復子を入れるとinclude文で作成する反復子を揃える必要があることを失念していました。 色々考えているうちにスキャナを弄れば行番号を埋め込ませることができそうな気がして、Boost.Spiritのコードと…

構文木を作る その6

インタプリタの実装はできました。 今日の差分 あとはこのインタプリタをライブラリ側に移動させないといけません。 このとき、どこまで汎用化させるべきかをフレーム情報(ファイル名、行番号)との兼ね合いから考えてみました。 ファイル名が変わるタイミン…

構文木を作る その5

今日はえらく中途半端な状態でコミットしてしまいました。 今日の差分 for文 switch文 module定義 class定義 を追加して、while文が作りかけです。 テストコードもとりあえず追加していて、while文が動かないのでコメントアウトしてあります。 今日詰まった…

構文木を作る その4

変数展開処理と文法の事前インスタンス化を追加しました。 今日の差分 前のコードとほとんど同じです。 前のバージョンでは、内部は行番号カウント付きの反復子で処理し、結果を返すときに元の反復子に戻していましたが、今回はパース結果に構文木が含まれる…

構文木を作る その3

今日は、構文木を評価してECHOだけ動くインタプリタまで作りました。 構文木の使い方は分かったので、他の機能の実装方法もおおよそ見当がつきました。 演算や制御構造は特に問題はなさそうです。 面倒なのは、ruleとincludeです。 今回はruleを何度もパース…

構文木を作る その2

Hamigaki.Bjamの改良用にSandboxにディレクトリを追加しました。 hamigaki/bjam2 svn copyとかすると前のコードが枷になって大胆な変更がやりにくいので、必要な箇所を切り貼りしながら書き直していき、最終的にtrunkにマージする形をとります。 今日はbjam_…

構文木を作る その1

VMware上でテストしていると、Hamigaki.ArchiversとHamigaki.Bjamのビルドがキツいです。 特にCygwinテスト用に使っているWindows2000だと仮想メモリの割り当てを増やすよう警告が出ます。 CPUファンの音も煩くて困るので、コードを見直すことにしました。 H…

context::output_stream()

昨日のbuiltin_rules_testがFailだったのは、Cygwinのg++パッケージにlibstdc++のDLL版が用意されていないせいで、std::coutがHamigaki.BjamのDLLとテストプログラムのexeの二箇所に生成されていたのが原因でした。 link=staticでビルドすれば回避可能ですが…

少し修正

BBv2 Tutorialを書いていて見つけたバグ修正をしました。 PATHそのものだけでなく、PATHで終わる環境変数もデリミタで分割するように修正 「フロー制御」を「制御フロー」に修正 例にos.environを追加

bjamの日本語の扱いが酷い件

VC++9.0対応の関係でSVNのtrunkからBoostを取ってきて、久々にbjamをビルドしたんですが、なぜかコンパイラの診断メッセージが化けます。 で、ソースを眺めてみると、execnt.cにこんなコードを発見しました。 /* clean up non-ascii chars */ int i; for ( i…

bjamの文法解説 その6

標準モジュール(のいくつか)、コンフィグファイル、.ENVIRONモジュールの説明を書きました。 http://hamigaki.sourceforge.jp/doc/html/bbv2.html これでbjamの説明はひとまず終了です。 あとは思いついたことをその都度書き足していきます。 かなり端折った…