System.Drawing.Image缓存以获得更好的性能

时间:2012-12-07 15:29:40

标签: c# .net caching graphics

我正在尝试优化从磁盘读取数百个图像的图形处理,处理它们并生成单个图像,我尝试优化的过程是从磁盘一遍又一遍地读取图像,其中一个选项我正在考虑阅读和缓存内存中的图像。在最简单的形式,我想使用字典如下。

更新:

  • 磁盘上的图片不会更改
  • 将有一个进程使用上次访问的时间戳来缓存来自缓存的较少使用的项目
  • 现在是单线程进程。
  • 平均图像大小约为400KB
  • 物理内存大小为16GB

这是个好主意吗?最重要的是它会起作用吗?

public class ImageCache
{
    protected Dictionary<string, System.Drawing.Image> ImageStore = new   Dictionary<string, System.Drawing.Image>(10000);




 public System.Drawing.Image Get(ImageReference imgRef)
 {
      System.Drawing.Image image;

        if (!ImageStore.TryGetValue(imgRef.Key, out image))
           image= CacheImageFromDisk(imageRef);
       return image;
 }

 System.Drawing.Image CacheImageFromDisk(ImageReference imgRef)
    {
      using (var f = new FileStream(imgRef.Path, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            var img=Image.FromStream(f);
            ImageStore.Add(imgRef.Key,img);
            return img;
        }
  }

    ~ImageCache()
    {
       //Dispose each item in ImageStore  and calll GC.Collect()
    }
}

4 个答案:

答案 0 :(得分:1)

对我而言,这是一个好主意,乍一看代码似乎有效。 无论如何要考虑:

  • 线程安全:如果图像上有多个线程, 你的chache目前不是线程安全的。
  • 内存消耗: 图像有时会消耗内存,请注意这可能 损害过程,甚至因记忆而降低性能 交换,在这种情况下,你会觉得程序比没有慢 缓存!

答案 1 :(得分:0)

  

最重要的是它会起作用吗?

可能。

  

这是个好主意吗?

这取决于您重复使用的重复/图像数量。缓存是内存和性能之间的权衡。如果这是应用程序的瓶颈(IO往往很难描述),你必须检查它给你带来显着加速的地方甚至更重要。

答案 2 :(得分:0)

关注的是记忆 填满内存后,您将返回磁盘IO 您是否有足够的内存用于您正在构建的单个图像和所有源文件 如果您开始将正在构建的单个映像分页到磁盘,则性能可能会降低。

有关优化的信息,请查看返回文件的原因 您是否可以流程化流程以一次使用单个源文件并完成它 或者你至少可以处理一个源文件块并完成它们。

字典是管理集合的正确方法 但到期并不是一种非常复杂的管理规模的方法 需要根据使用的内存清除字典 如果应用程序开始分页到磁盘那么这很糟糕。

对于最佳内存大小,请使用性能计数器和跟踪页面文件使用情况 但零不是目标,因为你会进行一些分页 我的经验是MSSQL将记忆最大化并保持在那里(除非你限制它)。 您的应用我的开始分页率为80% 没有标准%。

回到你的应用程序在使用和使用文件时不能更聪明吗?

如果你无法将所有内容都装入内存中,那么降压最好的就是固态硬盘。

答案 3 :(得分:0)

我想说在主存储器中缓存图像是一个非常糟糕的主意。内存可能会耗尽,甚至会导致整个系统的稳定性出现问题。更高分辨率的图像可能大约20 mb,有多少你会缓存吗?