C#缓存txt文件或使用file.ReadLines

C#缓存txt文件或使用file.ReadLines,c#,performance,caching,C#,Performance,Caching,我经常在相同的几个文件上使用File.ReadLines(),不知道以这种方式读取文件的开销是多少 我正在搜索txt文件中的每个文件id(哈希) 目前我正在使用这段代码,但不知道是否应该缓存这些索引文件。我犹豫不决的是,这些文件将被频繁编辑,因此每次将文件重新加载到缓存中都会对性能造成同样大的影响。在每次迭代中,我很可能会在文本文件中添加一行(不会有匹配项) 根据文件的不同路径,需要检查大约5-10个index.txt文件。。。所以每一个都需要缓存 缓存index.txt文件是更好的主意吗?Fi

我经常在相同的几个文件上使用File.ReadLines(),不知道以这种方式读取文件的开销是多少

我正在搜索txt文件中的每个文件id(哈希)

目前我正在使用这段代码,但不知道是否应该缓存这些索引文件。我犹豫不决的是,这些文件将被频繁编辑,因此每次将文件重新加载到缓存中都会对性能造成同样大的影响。在每次迭代中,我很可能会在文本文件中添加一行(不会有匹配项)

根据文件的不同路径,需要检查大约5-10个index.txt文件。。。所以每一个都需要缓存

缓存index.txt文件是更好的主意吗?File.ReadLines()是否有很多开销

感谢您的指点。

如果您有许多足够短的文件,缓存看起来是合理的:

  // Simplest, not thread safe
  private static Dictionary<String, String[]> s_Files = 
    new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);

  private static IEnumerable<String> ReadLines(String path) {
    String[] lines;

    if (s_Files.TryGetValue(path, out lines))
      return lines;
    else {
      lines = File.ReadAllLines(path);

      s_Files.Add(path, lines);

      return lines;   
    }
  }

  ...

  foreach (var myfile in allfiles) {
    ...
    // Note "ReadLines" insread of "File.ReadLines"
    foreach (var line in ReadLines(myfile.path + "\index.txt")) {
    }
  }
//最简单,不是线程安全的
专用静态字典s_文件=
新字典(StringComparer.OrdinalIgnoreCase);
专用静态IEnumerable可读行(字符串路径){
字符串[]行;
if(s_Files.TryGetValue(路径,输出行))
回流线;
否则{
lines=File.ReadAllLines(路径);
添加(路径、行);
回流线;
}
}
...
foreach(所有文件中的var myfile){
...
//注意“File.ReadLines”中的“ReadLines”
foreach(读取行中的变量行(myfile.path+“\index.txt”)){
}
}

比较两种实现—您当前的一种—和此缓存例程,然后决定是否要缓存。

我建议如下:

  • 将每个哈希文件的最后更新时间戳存储在内存中

  • 缓存哈希文件的内容

  • 访问缓存时,检查文件的上次更新时间戳是否大于存储在内存中的时间戳

  • 使用ConcurrentDictionary而不是Dictionary


  • 我认为你必须亲自测试这个问题,因为没有一个简单或准确的方法可以让任何人回答这个问题。我的直觉告诉我,使用
    字典
    会更快,但在测试之前你不会知道。构建并测试它。问题是你能将所有文件以任何方式存储在ram中吗?我的意思是这些都是5k文件,对吗?在性能方面,不要做假设。使用探查器测量执行时间,从中您可以确定开销是否可以接受。如果您不知道,那么很明显您没有问题。不要修复想象中的问题。@HansPassant这对C#非常重要-只要性能没有问题,忽略优化方面这很好,谢谢。但是,在我的示例中,如果没有匹配项,则会在index.txt文件中添加新行。这意味着需要将其重新加载到缓存中。这种情况经常发生,最后我使用了一个稍微修改过的版本(使用字典存储文件内容)。谢谢
    
      // Simplest, not thread safe
      private static Dictionary<String, String[]> s_Files = 
        new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);
    
      private static IEnumerable<String> ReadLines(String path) {
        String[] lines;
    
        if (s_Files.TryGetValue(path, out lines))
          return lines;
        else {
          lines = File.ReadAllLines(path);
    
          s_Files.Add(path, lines);
    
          return lines;   
        }
      }
    
      ...
    
      foreach (var myfile in allfiles) {
        ...
        // Note "ReadLines" insread of "File.ReadLines"
        foreach (var line in ReadLines(myfile.path + "\index.txt")) {
        }
      }