|組み込み用のプログラミング言語といえばLuaがよく使われるけど、最近はmrubyやsquirrelもあって選択肢が広がってきた感があるのでどういう特徴があるのかを知るためにベンチマークをやってみた。今回対象にしたのは以下。v15.3.7ここでのベンチマークは言語自体のスピードの比較ではなく、どちらかというと組み込む際に必要なオーバーヘッドやホスト言語側での処理にかかる部分に重点を置いた。ベンチマークの処理では、関数呼出し比較用のecho関数と、テーブル操作比較用のinvert関数を組み込み言語側に実装して、それを繰り返し呼び出すようにした。公平になるように、組み込み言語側の関数は初期化時にグローバルスコープ(組み込み言語側のグローバルスコープ)に登録しておき、すべて同じインターフェースから呼ぶようにした。使用したコードは以下。そのうち別の言語とか追加するかもしれない。所感Luaがパフォーマンスと組み込みやすさの点でやはり一番使いやすい。LuaJITをつかうとさらに数割速くなる。squirrelは言語機能的にはluaのスーパーセットという感じで、パフォーマンスもluaと同じ程度。ドキュメントはあまりない。V8はマルチスレッド環境や大規模なものには向いてるかもしれない。組み込みはちょっとめんどくさい。mrubyはechoだと意外と健闘しているがテーブル操作は速くない。組み込みはLuaと同じくらい簡単。eclにはもうちょっとがんばってほしい。組み込み方法に問題があるのかもしれない。使ったワークフローを試しています。FacebookやDropboxをはじめとして海外では割と良く使われているようですが、あまり国内には情報がないようなのでまとめておきます。PhabricatorでできることPhabricatorはコードレビューがメイン機能のようですが、それに留まらずソフトウェアの開発で必要なものがワンストップでまとまったプロジェクト管理ツールになっています。メニューのネーミングが独特でとっつきづらいですが、主に以下のような機能があります。いうコマンドラインから操作するためのツールも別途提供されており、開発のワークフローも含めた統合が意図されているようです。https://registry.hub.docker.com/u/yesnault/docker-phabricator/ただし、上記dockerfileから構築したコンテナはデフォルトだとメールは外部に送信できない設定になっています。コンテナに入ってメール設定を適宜修正して下さい。起動直後は色々設定を聞かれますが、特につまるようなところはないので省略します。Requestに似ていますが、レビュー対象のcommitをpushするのではなく、パッチを送る点が異なります。Phabricatorでは以下のようなフローで作業することになります。コードを修正した人(author)は、レビュワー(reviewer)を指定して変更内容をDifferentialに登録するreviewerは通知を受けてレビューをするreviwerがacceptしたら、authorはupstreamにpushするdiffをPhabricatorにコピペして登録することもできますが、基本的にはarcanist経由で作業することになります。Requestベースでも達成できます。Defferentialとarcanistを使えば簡単にレビュー依頼が投げられるので、開発者が自発的に適切な粒度でレビュー依頼する助けにはなりそうです。(Audit)Differentialではレビューが完了するまでpushを待つ必要がありますが、Auditはレビューを待たずにpushしてその後にレビューを実施するための機能です。急いでリリースする必要がある場合でも、Auditを用いてあとからレビューすることができます。Commitsというフラグをたてておいてタスクに積む、というような使い方になるようです。Haraldという機能を使えば特定の条件に合致するcommit(例えば変更が大きい、Differentialでレビューされていない、等)があった場合は自動的にAuditを生成させることもできます。requestのように使うこともできますが、推奨はされていないようです。所感もし開発管理のためにredmineやjiraをつかっているのであればPhabricatorは良い代替になりそうです。開発者向けに特化してる分、プロジェクトのタスクやバグ管理がソースコードとうまく統合されていて、ダッシュボードも柔軟にカスタマイズできます。githubのissueに不満を感じている人もPhabricatorのワークフローは試してみる価値があると思います。Requestの手軽さに比べるとやや煩雑に感じました。等のほうが導入しやすいかもしれません。デモPhabricatorが使えるので一通り試せます。デフォルトではかなりの頻度でリポジトリに対してポーリングしに行きます。負荷をかけ過ぎないように注意が必要です。Phabricator自体もそれなりの性能のマシンが必要です。環境によってはworker数を減らしたりmysqlのメモリサイズを調整しておく必要があります。diamondと呼ぶらしい。D3例えば以下のようなクラスではアップキャストをするときやBaseクラスのメンバにアクセスするときに曖昧性が生じる。{}};以下のようなコードをコンパイルしようとしてもエラーになる。^これを回避するためには明示的に中継するクラスを指定してやる必要がある。123,456}でも普通は継承元にそれぞれの別々の親を持つのではなく、共通の1つだけを持っていてほしい。それを解決するには仮想継承を使う。};このようにすればBaseクラスのインスタンスは1つだけになって曖昧性が解消される。pointsとは、スレッドのキャンセル種別がdeferredのときに、そこに到達したときにはじめて実際にそのスレッドのキャンセル要求が処理されるような関数のこと。pointsであることが要求されている。memsetのほうが大幅に遅くなる可能性があります。sizeof(type));カーネルはセキュリティ上の理由からメモリを0で初期化してからユーザプロセスに渡します。onlyな領域を複数プロセスで共有させることができるため、既に初期化してあるページであればこの処理を省略できる場合があります。brkで拡張した領域は0で初期化されているので、callocは新規確保した領域は初期化を省略することができ、結果的にcallocを実行したタイミングでは初期化が実際にはほとんど発生しない、ということがありえます。memsetの場合は実際にメモリへの書込みが発生する上、ページの共有もできなくなるためswapする可能性もあります。ちなみに、(カーネルではなく)calloc自身が0初期化する処理と、memsetの処理は微妙に違います。memsetは対象の領域がアラインされているかどうかについての情報なしに処理する必要があるので、境界部分は1byteずつやるしかありません。memsetのほうが遅いのかというと、コンパイラによってはアラインされていることを推測できる場合もあったり、callocはライブラリ関数なので移植性のために最適化しにくかったりするので、結局のところ微妙です。