我决定使用C#和C ++中的图像进行基准测试,以决定在我正在考虑为自己制作的项目中使用哪种语言。
我预计基准测试非常接近C ++可能会略微推进。
C#代码每次运行大约需要300ms(我每次运行100次),其中C ++代码大约需要1.5ms。
我的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 ++中,你不做这样的检查。那么检查有多重要?任何人都可以给我一个避免这种情况会不好的情况吗?
答案 0 :(得分:7)
是的,您的基准存在缺陷。问题是你忘了用位图实际做的东西。喜欢画它。
GDI +大大优化了图像的加载。与.NET优化加载程序集的方式非常相似。它完成了必要的事情,它读取文件的标题以检索基本属性。格式,宽度,高度,Dpi。然后,它创建一个内存映射文件,以创建到文件中像素数据的映射。但实际上并没有读取像素数据。
现在差异发挥作用。 System.Drawing.Image接下来实际读取像素数据。这会导致页面错误,操作系统现在读取文件并将像素数据复制到RAM中。非常需要,如果文件有任何问题,那么你将在FromFile()调用时获得异常而不是一段时间后,通常是当你的程序绘制图像并埋没在你没有编写的框架代码中时。 C#代码的基准标记乘以mmf 加上读取像素数据的时间。
C ++程序总是需要为读取像素数据付费。但是你没有衡量,你只测量了创建MMF的成本。
答案 1 :(得分:-2)
我知道的几点
有一种称为CLR的东西。如果所说的c ++框架(似乎是Qt)使用的系统调用不依赖于.net框架,那么显然它会快速运行。
关于c#=>在代码中调用它之前,可以加载该程序集。如果你这样做,那么你可以很好地发现它的坚牢度。
如果您使用Windows平台,那么除非有必要,否则MS不会降低其语言的执行速度。