Reflection for C ++のミニライブラリの概要

このトピックに関する控えめな情報のため、この記事では、C ++のReflectionで見つかったライブラリの簡単なレビューと比較を行います。 まず第一に、この情報はゲーム開発者にとって興味深いものです。



リフレクションのおかげで、次のことができます。

-オブジェクトのすべてのプロパティに関するメタ情報に簡単にアクセスできるため、インターフェイスを含むエディターを簡単に作成できます。

-多くのスクリプト言語(Lua、Python、JavaScriptなど)のバインディングを一度に追加します。

-自動シリアル化にメタ情報を使用します。

-オブジェクトのファクトリとして使用し、必要なインスタンスを作成し、名前タイプの文字列のみを使用します。

-より軽量な代替dynamic_castとして使用します。

-想像力やニーズに応じて、などなど。



次に、適度な機能のために各ライブラリの概要を順番に説明します。 それぞれについて:

-短い説明。

-そのようなクラスのバインディングと使用例:



class Test { public: int func(int a, int b) { return a + b; } };
      
      





-i5 3570K、Windows 8、Visual Studio 2013、Release x86でパフォーマンスを測定した結果(10,000,000クラスメソッド呼び出しと10,000,000メタメソッド検索+呼び出しを別々に測定)。



追加の構築手順とツール(qt mocやgccxmlなど)を必要としないライブラリのみが考慮されました。



図書館は、個人的な関心の高い順にリストされています。



1)ルアバインド



画像

github.com/rpavlik/luabind



LuaはバインドにLuabind(rpavlikのフォーク)を使用するようになりましたが、結果のメタ情報は他には使用されません。





 luabind::module(state) [ luabind::class_<Test>("Test") .def("func", &Test::func) ];
      
      







 local obj = Test() obj:func(1, 2)
      
      







ベンチマーク

-呼び出し-1100ms

-FindMetaMethod +呼び出し-1580ms



2)キャンプ



画像

projects.tegesoft.com/pm/projects/camp

github.com/tegesoft/camp



luabindに触発されたフランスの会社によって作成されました。 それは非常に文化的に見え、解決しました。

確かに、それは既に4年間目立って更新されていません。





 CAMP_TYPE(Test) camp::Class::declare<Test>("Test") .function("func", &Test::func); Test obj; camp::Class t = camp::classByName("Test"); camp::Function m = t->function("func"); camp::Value v = m->call(obj, camp::Args(1, 2)); auto result = v.to<int>()
      
      







ベンチマーク (構築に失敗し、別のライブラリのサイトから結果を取得した)

-呼び出し-6889ms <-非常に悲しい



3)cpgf



画像

www.cpgf.org/document/index.html

github.com/cpgf/cpgf



主な著者は中国人です。 うまくいきましたが、インターフェースは非常に複雑で、コードはまったく簡潔に見えません。 多くのプレフィックス、ネーミングへの追加、さまざまなインターフェイス、使用ルール(所有権の転送方法と転送時期など)。 簡単な例は表示されませんが、チュートリアルを見ると非常に目立つようになります-github.com/cpgf/cpgf/blob/develop/samples/tutorials/a01_reflect_to_global.cpp

同時に、すべてが単一のインターフェースに削減されます。これはもちろん喜ばしいことです。



大きなプラスは優れたドキュメントです。



追加の機能-シリアル化、Lua / JavaScript / Python、トゥイーン、独自のイベントシステムでバインドするためのターンキーソリューション。



バグ修正は12月に行われました。つまり、プロジェクトは死んでいません。





 cpgf::GDefineMetaClass<Test> ::define("Test") ._method("func", &CpgfTest::func); Test obj; cpgf::GMetaClass* t = cpgf::findMetaClass("Test"); cpgf::GMetaMethod* m = t->getMethod("func"); cpgf::GVariant v = m->invoke(&obj, 1, 2); auto result = cpgf::fromVariant<int>(v);
      
      







ベンチマーク

-呼び出し-1000ms

-FindMetaMethod + Invoke- 1135ms <-luabindより高速



4)RTTR



画像

www.axelmenzel.de/projects/coding/rttr



著者は、ドイツ人です。 Hooray-C ++ 11。 積極的に開発された、美しい構文、最新の機能、非常に満足しています。 近い将来、大幅なリファクタリングを伴う新しいバージョンが登場するはずです。



しかし今のところ、コードから判断すると、多くの簡単な解決策があります。そのため、パフォーマンスインジケーターが著しく悪化します。





 RTTR_DECLARE_STANDARD_TYPE_VARIANTS(Test); RTTR_REGISTER { rttr::class_<Test>() .method("func", &Test::func); } Test obj; rttr::type t = type::get("Test"); rttr::method m = t.get_method("func"); rttr::variant v = m.invoke_variadic(obj, {1, 2}); auto result = v.get_value<int>();
      
      







ベンチマーク

-呼び出し-1780ms

-FindMetaMethod +呼び出し-2290ms



5)uMOF



画像

bitbucket.org/occash/umof



著者はロシア語を話し、すべての質問に積極的に答えます。 私が理解しているように、QTの素晴らしい印象の下で作成されました。 もう一度、C ++ 11(これらすべてのconstexprとその他の喜び)。 積極的に開発しています。 近い将来、大幅なリファクタリングとアクセラレーションを備えた新しいバージョンが登場し、テストされました。



条件付きマイナス-マクロを使用してメタ情報を作成する必要がありますが、これは実装機能によるものです(後で説明します)。





 U_DECLARE_API(Test, METHODS); U_DECLARE_METHODS(Test) { U_METHOD(func) }; const Api* api = U_API(Test)::api(); Method m = api->method(api->indexOfMethod("func(int,int)")); int result; m.invoke(&obj, result, {1, 2}));
      
      







ベンチマーク

-呼び出し-115ms <-マジック(旧バージョン420では、他のバージョンよりも優れています)

-FindMetaMethod + Invoke- 1780ms <-はあまり良くありませんが、おそらく最適化されます



呼び出しは、他のライブラリの最高の結果よりもほぼ9倍高速です。



著者自身がこれについて書き、彼の決定を他の人と比較しました。 古いバージョンのグラフィックと写真をここで入手するには-www.gamedev.net/page/resources/_/technical/general-programming/implementing-a-meta-system-in-c-r3905

また、どのライブラリがプロジェクトのコンパイル時間とリンク時間に影響するか、およびバイナリがどれだけ重いかについての比較もあります。



全体の結果
ルアビンド キャンプ cpgf RTTR uMOF
呼び出す 1100 6889 1000 1780 115
FindMetaMethod +呼び出し 1580 x 1135 2290 1780




おわりに



最も近代的で簡潔で活気のあるライブラリ-uMOF、RTTR。

最も豊富な機能はcpgfです。

卓越したパフォーマンス:

-uMOF(実装機能、信じられないほど高速な呼び出し、コンパイルとバイナリサイズの最小オーバーヘッドによる);

-cpgf(現在、最も一般的なユースケースであるFindMetaMethod + Invokeの最速の結果)。



議論の提案



1)どの種類のゲーム開発者がライブラリを選択する必要がありますか?

cpgfはしっかりと設計されており、良い結果を示していますが、このオーバーヘッドはinvokeにとって重要ですか? たとえば、より最新のRTTRを優先する場合があります。 10,000,000コールあたり2290ミリ秒は、1秒あたり4,366,812コールです。 60 FPSでフレームあたり72,780コール。 つまり、各フレームで約700の呼び出しが行われた場合、60 FPSではこれはフレーム時間の1%未満になります。

同時に、uMOFは優れた結果を示します。これにより、最大強度で使用することが可能になります(計画されています)。 しかし、まだ完成しておらず、いくつかの機能が欠けています。

2)たぶんいくつかのライブラリが欠落していますか? レビューに追加できます。

3)これらのライブラリについての経験から何を知っていますか? ここでのレビューは表面的なものであり、おそらくあなたの経験から、あるライブラリに賛成または反対するいくつかの重要な機能について語っています。



コメントありがとうございます。



-更新1:ライブラリのパフォーマンスをluabindと比較することは完全に正しいとは限りません。 なぜなら luabindでメソッドを呼び出すには、メタメソッドを見つけるだけでなく、lua仮想マシンを操作する必要があります。 このトピックに関する有用な情報があり次第、記事の更新を試みます。



All Articles