GDI+Image比C#Image快得多
GDI+ Image EXTREMELY faster than C# Image
我决定在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++中,你不会这样做检查。那么,这种检查有多重要呢?有人能给我一个避免这种情况会很糟糕的情况吗?
是的,您的基准测试存在缺陷。问题是,您忘记了实际对位图执行操作。就像油漆一样。
GDI+极大地优化了图像的加载。与.NET优化加载程序集的方式非常相似。它只做一些必要的事情,读取文件的头以检索基本属性。格式、宽度、高度、Dpi。然后,它创建一个内存映射文件,以创建到文件中像素数据的映射。但实际上并没有读取像素数据。
现在,差异开始发挥作用。System.Drawing.Image接下来实际读取像素数据。这会导致页面错误,操作系统现在读取文件并将像素数据复制到RAM中。非常理想的是,如果文件有任何问题,那么您将在FromFile()调用中得到一个异常,而不是稍后,通常是当您的程序绘制图像并隐藏在您没有编写的框架代码中时。C#代码的基准点乘以mmf的创建加上像素数据的读取。
C++程序总是要为读取像素数据付费。但你没有衡量这一点,你只衡量了创建MMF的成本。
我知道的几个要点
有一种东西叫做CLR。如果上述c++框架(似乎是Qt)使用了不依赖于.net框架的系统调用,那么它显然会运行得很快。
关于c#=>可以在代码中调用该程序集之前加载该程序集。如果你这样做,那么你可以发现它的牢度很好。
如果你使用windows平台,那么除非有必要,否则MS不会降低自己语言的执行速度。
- 为什么通过引用返回向量比通过移动返回要快得多?
- 禁用优化后,quick-bench.com 基准测试要快得多
- C++ OpenMP 斐波那契:1 个线程的执行速度比 4 个线程快得多
- 为什么迭代 std::array 比迭代 std::vector 快得多?
- 为什么<wstring>使用自定义 wcscmp 和 wmemcmp 比较器对向量进行排序比默认快得多?
- C 为什么在原始双阵列中的分配似乎比双变量分配要快得多
- Linux 在从文件中读取数据并放入矢量时比 Windows 快得多.txt.我将如何加速Windows以做同样的事情
- 为什么 C 数组比 std::array 快得多?
- 为什么 pcre 正则表达式比 c++11 正则表达式快得多
- 为什么数组比向量快得多
- 为什么 ifstream::read 比使用迭代器快得多
- 为什么其中一个比另一个快得多
- GDI+Image比C#Image快得多
- 为什么堆栈内存的 memcpy 比堆内存快得多
- 为什么使用TBB的OpenCV函数比基于Boost的实现快得多
- 为什么多个文件的编译速度比合并文件快得多
- 为什么Windows C++多线程IOPS比IOMeter快得多
- 为什么STL算法使用指针比std::向量迭代器快得多
- 为什么使用 mkdir () 函数比使用 system ('mkdir 路径')快得多?
- 为什么Eigens-mean()方法比sum()快得多