Delphi/C++ Builder Windows 10 1709位图操作极慢

Delphi/C++ Builder Windows 10 1709位图操作极慢,delphi,c++builder,tbitmap,timagelist,Delphi,C++builder,Tbitmap,Timagelist,有人遇到过这个问题吗 它出现在Windows10升级到1709之后。 在一些系统启动时间(几个小时)后,位图加载,imagelist项添加变得非常缓慢。256x256 BMP加载时间超过10秒…执行此操作时,它100%占用一个CPU核心。 因此,通常在几秒钟内启动的编译应用程序现在可以在几分钟内启动 我经常使用休眠/恢复。 显示器驱动程序已经有一年多的历史了,所以这不是问题所在 对此有何评论 更新: 我发现这种情况发生在使用Canvas.Pixels的代码中,因此可以更改,但速度仍然非常慢 更新

有人遇到过这个问题吗

它出现在Windows10升级到1709之后。 在一些系统启动时间(几个小时)后,位图加载,imagelist项添加变得非常缓慢。256x256 BMP加载时间超过10秒…执行此操作时,它100%占用一个CPU核心。 因此,通常在几秒钟内启动的编译应用程序现在可以在几分钟内启动

我经常使用休眠/恢复。
显示器驱动程序已经有一年多的历史了,所以这不是问题所在

对此有何评论

更新: 我发现这种情况发生在使用Canvas.Pixels的代码中,因此可以更改,但速度仍然非常慢

更新2: 用扫描线操作代替扫描线操作加快了速度。最近的Windows修补程序一定制作了画布。像素的使用量越大,速度就越慢

GDI画布像素[x][y]速度较慢

它执行许多检查和颜色转换,你不知道它实际上是几十个子载波,如果不是几百子载波的话。这就是为什么它如此缓慢,与Win10无关。这种行为从windows开始就一直存在,至少据我所知,这是GDI的问题,不是VCL的问题,与Borland/Embarcadero VCL无关。因此,不要大量使用像素[x][y]。在某些机器上,即使以这种方式清除1024x1024映像,也可能需要大约一秒钟的时间

这是Borland/Embarcadero特定于纯GDI的,您需要使用位锁定。每个位图都有此属性/函数,用于返回指向任意y轴位图原始数据的指针。它的速度与像素[y][x]一样慢,但如果位图不改变其像素格式,也不调整其大小,则指针仍保持不变

这可用于直接像素访问,无需任何性能影响。您只需记住每个位图的所有行,如调整大小/重新加载到自己的数组中。然后就用这个。如果使用得当,这通常比像素[x][y]快约10000x倍

我通常在C++中将扫描行指针复制到自己的数组中: //好的,雷斯脱有一些位图 图形::TBitmap*bmp=新图形::TBitmap; bmp->宽度=100; bmp->高度=100; //这是在任何LoadFromFile、Assign或resize之后直接访问像素所必需的 bmp->HandleType=bmDIB;//允许使用扫描线 bmp->PixelFormat=pf32位;//32位与int相同,因此我们可以使用int*作为指针像素 DWORD**pyx=新DWORD*[bmp->高度]; 对于int y=0;yHeight;y++pyx[y]=DWORD*bmp->扫描线[y]; //现在我们可以像这样快速渲染像素: pyx[10][20]=0x0000FF00;//x=20,y=10处的绿点 //并快速阅读: DWORD col=pyx[10][20]; 所以把它移植到Delphi。请注意,在某些像素格式上,颜色是RGB而不是BGR,反之亦然,因此在某些情况下,您需要反转颜色的R、G、B顺序,尤其是预定义的顺序

由于并没有检查,所以不要访问位图之外的像素,这很可能引发访问冲突

最后,不要忘记在不再需要pyx阵列时或在新分配之前释放pyx阵列

GDI画布像素[x][y]速度较慢

它执行许多检查和颜色转换,你不知道它实际上是几十个子载波,如果不是几百子载波的话。这就是为什么它如此缓慢,与Win10无关。这种行为从windows开始就一直存在,至少据我所知,这是GDI的问题,不是VCL的问题,与Borland/Embarcadero VCL无关。因此,不要大量使用像素[x][y]。在某些机器上,即使以这种方式清除1024x1024映像,也可能需要大约一秒钟的时间

这是Borland/Embarcadero特定于纯GDI的,您需要使用位锁定。每个位图都有此属性/函数,用于返回指向任意y轴位图原始数据的指针。它的速度与像素[y][x]一样慢,但如果位图不改变其像素格式,也不调整其大小,则指针仍保持不变

这可用于直接像素访问,无需任何性能影响。您只需记住每个位图的所有行,如调整大小/重新加载到自己的数组中。然后就用这个。如果使用得当,这通常比像素[x][y]快约10000x倍

我通常在C++中将扫描行指针复制到自己的数组中: //好的,雷斯脱有一些位图 图形::TBitmap*bmp=新图形::TBitmap; bmp->宽度=100; bmp->高度=100; //这是在任何LoadFromFile、Assign或resize之后直接访问像素所必需的 bmp->HandleType=bmDIB;//允许使用扫描线 bmp->PixelFormat=pf32位;//32位与int相同,因此我们可以使用int*作为指针像素 DWORD**pyx=新DWORD*[bmp->高度]; 对于int y=0;yHeight;y++pyx[y]=DWORD*bmp->扫描线[y]; //现在我们可以像这样快速渲染像素: pyx[10][20]=0x0000FF00;//x=20,y=10处的绿点 //并快速阅读: DWORD col=pyx[10][20]; 所以把它移植到Delphi。请注意,在某些像素格式上,颜色是RGB而不是BGR,反之亦然,因此在某些情况下,您需要反转颜色的R、G、B顺序,尤其是预定义的顺序< /p> 由于并没有检查,所以不要访问位图之外的像素,这很可能引发访问冲突

最后,不要忘记在不再需要pyx阵列时或在新分配之前释放pyx阵列


显示器驱动程序已经有一年多的历史了,所以这不是问题所在。你现在觉得更新更好,对吗?尤其是当操作系统升级时!没有更新的驱动程序可用,而且问题只是最近才出现,所以我认为这可能不是系统发生变化的原因。请…哦,是的,问题一定是在Delphi中,而不是在您的代码中。。。即使没有生成MCVE,使用TBitmap.Canvas.Pixels属性通常也会很慢。要快速访问像素,请改用TBitmap.ScanLine属性。看,显示器驱动程序已经有一年多的历史了,所以这不是问题所在。你现在觉得更新更好,对吗?尤其是当操作系统升级时!没有更新的驱动程序可用,而且问题只是最近才出现,所以我认为这可能不是系统发生变化的原因。请…哦,是的,问题一定是在Delphi中,而不是在您的代码中。。。即使没有生成MCVE,使用TBitmap.Canvas.Pixels属性通常也会很慢。要快速访问像素,请改用TBitmap.ScanLine属性。看。我没有费心去检查这个,但我很好奇,在内核隔离补丁崩溃之后,像素是否变得特别慢。@J。。。我不这么认为,因为像素总是太慢,但我只是猜测。我敢打赌,新补丁改变了应用程序的计时行为,即使进程调度上的一个小变化也会产生很大的影响,特别是对多线程应用程序,它很可能已经非常接近甚至略高于断点。我会先检查计时器代码的持续时间。如果超过了它们的间隔,尝试将计时器间隔更改为安全的大值来测试它是不好的。最安全的方法是测量时间并用QueryPerformanceCounter绘制图表。但你的观点是possible@J... 我也是这么想的,像素使用了关键部分,所以最近的一些windows补丁可能会减慢速度。@kgz好吧,我刚刚测试了一个打补丁和未打补丁的Win7系统,除了两个系统相同的gen i7,不同的时钟之间的预期性能差异之外,没有任何可测量的差异。像素以前很慢,现在仍然很慢,但似乎没有比以前慢多少。可能Win10不一样,还没有测试。像素[]一直很慢。扫描线速度非常快,也可以进行优化,因此您不必在每个位图行的循环中调用它,但所获得的性能增益通常很小。我没有费心检查这一点,但我很好奇,在内核隔离补丁崩溃之后,像素是否变得特别慢。@J。。。我不这么认为,因为像素总是太慢,但我只是猜测。我敢打赌,新补丁改变了应用程序的计时行为,即使进程调度上的一个小变化也会产生很大的影响,特别是对多线程应用程序,它很可能已经非常接近甚至略高于断点。我会先检查计时器代码的持续时间。如果超过了它们的间隔,尝试将计时器间隔更改为安全的大值来测试它是不好的。最安全的方法是测量时间并用QueryPerformanceCounter绘制图表。但你的观点是possible@J... 我也是这么想的,像素使用了关键部分,所以最近的一些windows补丁可能会减慢速度。@kgz好吧,我刚刚测试了一个打补丁和未打补丁的Win7系统,除了两个系统相同的gen i7,不同的时钟之间的预期性能差异之外,没有任何可测量的差异。像素以前很慢,现在仍然很慢,但似乎没有比以前慢多少。可能Win10不一样,还没有测试。像素[]一直很慢。扫描线速度非常快,还可以进行优化,因此您不必在每个位图行的循环中调用它,但获得的性能增益通常很小。