1

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

更新:

  • 磁盘上的图像不会改变
  • 将有一个过程使用上次访问的时间戳从缓存中过期较少使用的项目
  • 现在它的单线程进程。
  • 平均图像大小约为 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

4 回答 4

1

对我来说这是一个好主意,乍一看,代码似乎可以工作。无论如何考虑:

  • 线程安全:如果您有多个线程在处理图像,那么您的 chache 目前不是线程安全的。
  • 内存消耗:图像有时会消耗内存,注意这可能会损害进程,甚至由于内存交换而降低性能,在这种情况下你会感觉程序比打开缓存慢!
于 2012-12-07T15:35:02.673 回答
0

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

为了进行优化,请查看为什么要返回文件。
您可以简化流程以一次使用单个源文件并完成它。
或者你至少可以处理一个源文件块并完成它们。

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

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

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

如果您无法将所有内容都放入内存中,那么最划算的是固态磁盘。

于 2012-12-07T15:43:18.857 回答
0

我会说将图像缓存在主内存中是一个非常糟糕的主意。内存可能会被用完,甚至会导致整个系统的稳定性出现问题。更高分辨率的图像可能在 20 mb 左右,你会缓存多少?

于 2012-12-07T15:49:45.180 回答
0

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

它可能。

这是一个好主意吗?

这取决于您重复使用的重复/图像有多少。缓存是内存和性能之间的权衡。您必须检查它在哪里可以显着加快速度,如果这是应用程序的瓶颈(IO 往往难以分析),则更重要的是。

于 2012-12-07T15:38:29.800 回答