これは実際には非常に複雑な質問です。残念ながら、完全に答えるには、基本的にそれを書いてテストする必要がありますが、答えが得られるまで、オンザフライの POCO 生成を見ないことを強くお勧めします! 基本的に、今のところそのステップは無視してください。
パフォーマンスに関するもう 1 つの重要な問題は、どの程度の速度が必要かということです。私が絶対に最初にすることは、機能する最も簡単なことであり、それを測定します。最も簡単に動作するのは、それを にロードし、DataTable
そのデータテーブルを ( を使用して) シリアル化することRemotingFormat = RemotingFormat.Binary;
です。砂の中の行を提供する 10 行のコードで:
var dt = new DataTable();
dt.Load(yourDataReader);
//... any access tests
dt.RemotingFormat = SerializationFormat.Binary;
using (var file = File.Create(path))
{
var bf = new BinaryFormatter();
bf.Serialize(file, dt);
}
// ... also check deserialize, if that is perf-critical
通常はどちらもお勧めDataTable
しBinaryFormatter
ませんが、... この場合は大げさではないようです。
個人的には、binary- remotingDataTable
-mode が実際にはひどいものではないことがわかると思います。
次のステップは、大きな努力をしなくても他に何が機能するかを確認することです。例えば:
したがって、次の行に沿って(純粋にそれがより良いかどうかを確認するために)例示的なクラスを作成したくなるでしょう。
[DataContract]
public class Foo {
[DataMember(Order=1)] public int Id {get;set;}
[DataMember(Order=2)] public string Name {get;set;}
// ... more props
// IMPORTANT: make this representative - basically, the same data
// that you had in the data-table
// note also include any supporting info - any indexers and interface
// support that your core code needs
}
[DataContract]
public class FooWrapper { // just to help in the test
[DataMember(Order=1)] public List<Foo> Items {get;set;}
}
同じテストを実行します (メイン コードはインデクサー アクセスのみを使用し.Query<Foo>(...)
ますが、今のところ dapper に API を使用させます):
var data = conn.Query<Foo>(...).ToList(); // dapper
//... any access tests, just using the indexer API
using (var file = File.Create(path))
{
var wrapper = new FooWrapper { Items = data };
Serializer.Serialize(file, wrapper); // protobuf-net
}
// note that you deserialize via Serializer.Deserialize<FooWrapper>(file)
これのポイントは、これにより、何が達成できるかという点で期待するのが合理的であることについて、ある程度の限界が得られるということです。dapper/protobuf-net の代わりに独自のマテリアライザー/シリアライザーを自由に使用してください。ただし、これら 2 つは主にこのようなシナリオ向けに大幅に最適化されていることを謙虚に申し上げておきます。
下限と上限があれば、「それだけの価値があるか」という質問に答える賢明なデータが得られます。実行時にオブジェクトを生成することはそれほど難しくありませんが、ほとんどの人が行う必要があるよりも多くの作業が必要です。また、生成された型を可能な限り再利用するように細心の注意を払う必要があります。そのルートに進む場合、protobuf-net にはSerializer.NonGeneric
orを介した完全に非ジェネリックな API があることに注意してくださいRuntimeTypeModel.Default
(3 つのオプションはすべて同じコアになります)。Dapperにはありませんが、喜んで追加します (インスタンスを受け入れType
ます)。とりあえず、その 1 つのステップにMakeGenericMethod
/を使用することもできます。Invoke
「それだけの価値はありますか」と直接答えていないことは承知していますが、それは意図的なものです。シナリオに直接適用しないと答えられません。うまくいけば、私は代わりに、あなたのシナリオにどのように答えることができるかについていくつかのヒントを提供しました. 私はあなたの調査結果を聞くことに非常に興味があります.
それだけの価値があるとわかっている場合にのみ (上記の場合、約 1 時間の作業が必要になると予想されます)、型を生成するという手間をかけます。その場合は、Sigilの使用をお勧めします。これにより、IL 生成のストレスが大幅に軽減されます。