免責事項: 私は Math.NET Numerics を保守しています。
Math.NET Numerics のようなツールキットが提供しようとする主な価値は、開発者の生産性です。特に、この分野の博士号を取得していない人にとっては、これらの非常に複雑なアルゴリズムを自分で実装するのに苦労したり、多くの時間を無駄にしたりします。彼らの実際の問題に時間を費やすこと。
次に、必要な機能が以前に他の人によって使用されている可能性があります。それらの一部は、すでにいくつかの問題を発見して指摘し、改善に貢献している可能性があります。ユーザーが増えると、コードの品質と堅牢性が向上します。残念ながら、これには大きな欠点もあります。コードをより一般的にする傾向があるため、必要なことを正確に実行する高度に専門化された実装よりも効率が低下することがよくあります。
これはすべて、Cody Gray のコメントの行に沿っています: 動作し、十分に高速である場合は使用してください。そうでない場合は、修正して動作させる (そして高速にする) か、動作する別のツールキットを選択するか、必要なものを正確に実装してください。幸いなことに、Math.NET Numerics にはさらにいくつかのオプションがあります。以下を参照してください。
そのため、私はあなたの結論に同意します。複雑な操作が実際に必要ない場合は、非常に大きなデータを操作しないでください。ただし、パフォーマンスは重要です。配列や別のデータ構造を直接使用しても問題はありません (特に F# では、個人的には、生のネイティブ データ構造を C# よりも頻繁に検討します)。もちろん、これにはいくつかの利便性が失われるという代償が伴います。また、より多くの操作が必要になったときにツールキットを再実装することになるリスクもあります。最終的には、これがプロジェクトにとってどれほど重要であるか、および独自の数学コードを維持するためにリソースと時間を費やすことができるかどうかにも依存します。
それにもかかわらず、私自身の経験では、コードを所有すること (変更を加えてすぐに有効にすることができる) と、コードをシンプルで集中的に保つこと (つまり、必要なことだけを正確に実行すること) が有利な場合がよくあります。
Math.NET 数値に固有
- 非常に具体的な管理された実装は、常に一般的な管理された実装よりも優れています。ただし、管理された実装は、管理された代替手段よりも大幅に遅くなるべきではありません。結局のところ、私たちのアルゴリズムは配列に対して直接動作するだけでなく、内部的にも動作します (適切に最適化されている場合)。代替アルゴリズムがはるかに高速である場合は、実装をその代替アルゴリズムに置き換える方がよいようですので、それについてお知らせください (または、変更を提供することをお勧めします)。
- MKL のようなネイティブ プロバイダーを活用できる道にたどり着き、大規模なデータを処理する場合、より高いレベルの抽象化にもかかわらず、Math.NETの方がはるかに高速であることが期待されます。
- Math.NET Numerics のすべてのコード パスが、まだ等しく最適化されているわけではなく、ネイティブ プロバイダーを利用しているわけでもありません。線形代数については、過去数回のマイナー バージョンで多くの作業が行われたため、徐々にではありますが改善されています。まだ多くの作業が必要です (特にスパース型の場合)。あなたの場合、ほとんど最適化されていないパスにヒットした可能性があります。したがって、この特定のケースに取り組むことができるように、実際にあなたのコード サンプルに非常に興味があります。
Math.NET Numerics パフォーマンスのヒント
- ネイティブ プロバイダーを使用する
- Control クラスの並列化設定を少し試してみてください (ただし、v2.4 までの並列化の実装は実際には非常に悪いことがわかっており、v2.5 で完全に置き換える予定です。最初のベンチマークは有望です)。
- 独自の操作を実装するときは、At/インデクサーへのアクセスを避け、代わりに生の配列に直接アクセスしてください (.Storage を参照)。
- 多くの操作で、結果のベクトル/行列を指定できます。これは、オペランドの 1 つ (インプレース) と同じになることもあります。すべての操作で新しい配列を作成することを回避するため、非常に大きなデータを扱う場合にメモリ負荷を軽減します。残念ながら、コードを醜くします。