2

私は、C# と C++ でイメージの読み取りをベンチマークして、自分で作ろうと考えているプロジェクトで使用する言語を決定することにしました。
ベンチマークは C++ と非常に近いものになると予想していましたが、おそらくわずかに先行しています。

C# コードは各実行に約 300 ミリ秒かかります (私は各テストを 100 回実行しました)、C++ コードは約 1.5 ミリ秒かかります。

私のC#コードは間違っていますか? 私はそれをひどくベンチマークしていますか?それとも、本当にこれだけ遅いのでしょうか?

私が使用したc#コードは次のとおりです。

Stopwatch watch = new Stopwatch();

watch.Start();
Image image = Image.FromFile(imagePath);
watch.Stop();

Console.WriteLine("DEBUG: {0}", watch.ElapsedMilliseconds);

そして、C++ コードはほぼ次のように要約されます。

QueryPerformanceCounter(&start);
Image * img = Image::FromFile(imagePath);
QueryPerformanceCounter(&stop);
delete img;
return (stop.QuadPart - start.QuadPart) * 1000.0 / freq.QuadPart;

どの言語に関係なく、最終的には Image オブジェクトにする必要があります。必要な機能を提供するためです。

================================================== =====================

xanatos がコメントで指摘したように、Image.FromFile はチェックを行います。

より具体的には、これは:

num = SafeNativeMethods.Gdip.GdipImageForceValidation(new HandleRef(null, zero));
if (num != 0)
{
    SafeNativeMethods.Gdip.GdipDisposeImage(new HandleRef(null, zero));
    throw SafeNativeMethods.Gdip.StatusException(num);
}

代わりに Image.FromStream() を使用すると、これを回避できます。

私が疑問に思っているのは、これを回避して無効な画像ファイルをロードしようとすると、OutOfMemory 例外がスローされることです。
C++ では、このようなチェックは行いません。では、このチェックはどれほど重要なのでしょうか。これを避けるのが悪い状況を誰か教えてもらえますか?

4

2 に答える 2

7

はい、あなたのベンチマークには欠陥があります。問題は、実際にビットマップで何かをするの忘れていることです。それをペイントするように。

GDI+ は、画像の読み込みを大幅に最適化します。.NET がアセンブリの読み込みを最適化する方法と非常によく似ています。必要な処理だけを行い、ファイルのヘッダーを読み取って重要なプロパティを取得します。フォーマット、幅、高さ、Dpi。次に、メモリ マップト ファイルを作成して、ファイル内のピクセル データへのマッピングを作成します。しかし、実際にはピクセルデータを読み取りません。

今、違いが出てきます。次に、System.Drawing.Image は実際にピクセル データを読み取ります。これによりページ フォールトが発生し、オペレーティング システムはファイルを読み取り、ピクセル データを RAM にコピーします。ファイルに何か問題がある場合、通常はプログラムが画像を描画し、作成していないフレームワーク コードに埋め込まれている場合に、後で例外が発生するのではなく、FromFile() 呼び出しで例外が発生します。C# コードのベンチマークは、mmf の作成とピクセル データの読み取りの時間計っています。

C++ プログラムは、ピクセル データの読み取りにも常に料金を支払う必要があります。しかし、あなたはそれを測定しませんでした。MMF を作成するコストを測定しただけです。

于 2012-07-18T17:56:38.413 に答える
-2

私が知っているいくつかのポイント

CLRというものがあります。上記のc ++フレームワーク(Qtのようです)が.netフレームワークに依存しないシステムコールを使用した場合、明らかに高速に実行されます。

c#について=>コードで呼び出す前にそのアセンブリをロードすることができます。そうすれば、かなりの堅牢性を見つけることができます。

Windows プラットフォームを使用している場合、必要がない限り、MS は独自の言語の実行速度を低下させません。

于 2014-03-12T08:29:03.713 に答える