Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 定期返回位图的函数是否应该重新使用它们?_C#_.net_Vb.net_Image_Instantiation - Fatal编程技术网

C# 定期返回位图的函数是否应该重新使用它们?

C# 定期返回位图的函数是否应该重新使用它们?,c#,.net,vb.net,image,instantiation,C#,.net,Vb.net,Image,Instantiation,我有一个函数,它返回一个位图,在面板中用作背景,有时我不得不调用它来根据参数创建一个新的背景 (由于此面板有两个绘图功能(背景不需要像前景那样经常更改),因此不只是在Paint事件上绘图。) 所以我的问题是:如果我使用旧的背景缓冲区作为参数,并利用它,而不是每次调用函数时都创建一个新的位图,是否会有(不仅仅是象征性的)性能提升?是的,我可以想象你会获得相当多的提升 首先,您的内存约束将更好地有界。如果您一直在创建位图,是什么阻止您的客户端代码保留位图并耗尽内存 在任何大型系统中,分配通常是最昂贵

我有一个函数,它返回一个
位图
,在面板中用作背景,有时我不得不调用它来根据参数创建一个新的背景

(由于此面板有两个绘图功能(背景不需要像前景那样经常更改),因此不只是在
Paint
事件上绘图。)


所以我的问题是:如果我使用旧的背景缓冲区作为参数,并利用它,而不是每次调用函数时都创建一个新的位图,是否会有(不仅仅是象征性的)性能提升?

是的,我可以想象你会获得相当多的提升

首先,您的内存约束将更好地有界。如果您一直在创建位图,是什么阻止您的客户端代码保留位图并耗尽内存

在任何大型系统中,分配通常是最昂贵的事情之一。对于创建成本高昂的对象来说,重用无疑是一件好事。垃圾收集也会减少打嗝的次数


<强>编辑< /强>。您还可以考虑维护自己的Bitmaps池,而不要求调用方在现有的池中传递。确保您记录了位图的所有权,并且调用者应该将其视为只读的(是否可以将其包装在某个不可变的对象中?)。这样,您就可以在自己的时间内创建/处理,而不需要客户提供任何东西。

是的,我可以想象,您会收获很多

首先,您的内存约束将更好地有界。如果您一直在创建位图,是什么阻止您的客户端代码保留位图并耗尽内存

在任何大型系统中,分配通常是最昂贵的事情之一。对于创建成本高昂的对象来说,重用无疑是一件好事。垃圾收集也会减少打嗝的次数


<强>编辑< /强>。您还可以考虑维护自己的Bitmaps池,而不要求调用方在现有的池中传递。确保您记录了位图的所有权,并且调用者应该将其视为只读的(是否可以将其包装在某个不可变的对象中?)。这样,您就可以在自己的时间内创建/处理位图,而不需要客户端提供任何信息。

是的,在绘制时运行的代码中重新创建位图通常成本太高,并且绘制速度太慢。保留位图副本可以解决速度问题,但代价是需要更多内存

注意,可以使用标准控件.BuffGrimDimay属性,考虑使用它。您只需要添加代码,当需要不同背景图像的条件发生变化时更新该属性(并调用Invalidate)。绘图是自动的

第二个效率考虑因素是预缩放位图以完全适合控件的ClientSize,避免在绘制时重新缩放位图。节省了很多钱,尤其是位图很大的时候。但需要重写OnResize方法,以便重新生成缩放位图。如果在调整窗体大小时绘制速度过慢,则需要连接窗体的ResizeEnd事件


创建格式为32bpppargb像素格式的位图时,它在大多数视频适配器上的绘制速度大约是其他格式的10倍。

是的,在绘制时使用代码重新创建位图通常成本太高,并且绘制速度太慢。保留位图副本可以解决速度问题,但代价是需要更多内存

注意,可以使用标准控件.BuffGrimDimay属性,考虑使用它。您只需要添加代码,当需要不同背景图像的条件发生变化时更新该属性(并调用Invalidate)。绘图是自动的

第二个效率考虑因素是预缩放位图以完全适合控件的ClientSize,避免在绘制时重新缩放位图。节省了很多钱,尤其是位图很大的时候。但需要重写OnResize方法,以便重新生成缩放位图。如果在调整窗体大小时绘制速度过慢,则需要连接窗体的ResizeEnd事件


创建格式为32bpppargb像素格式的位图时,它在大多数视频适配器上的绘制速度大约是其他格式的10倍。

哦,实际上我知道我必须处理位图-我怀疑的是新的dispose new dispose[…]周期。但即使如此,分配也会影响性能,对吗?@Camilo,重复分配大型对象时需要注意的一点是,您可以分割大型对象堆,这可能导致抛出OutOfMemoryException,即使内存仍然可用。我不确定位图是否有这个问题(它可能是包装了一个非托管内存缓冲区),但如果您经常使用大字节[]对象,肯定会有这个问题。Dan Bryant关于内存碎片的考虑非常相关!问题解决了我想,我会记住位图和其他流的这一点。SB是对的,位图像素存储在非托管内存中,而不是LOH。现在我已经阅读了您的编辑,在不可变对象中包装意味着什么?如果只是为了避免写入,我认为没有问题(我可以记录并记住)。哦,实际上我知道我必须处理位图-我怀疑的是新的dispose new dispose[…]周期。但即使如此,分配也会影响性能,对吗?@Camilo,重复分配大型对象时需要注意的一点是,您可以分割大型对象堆,这可能导致抛出OutOfMemoryException,即使内存仍然可用。我不确定位图是否有这个问题(它可能是包装了一个非托管内存缓冲区),但是