2011-05-03 90 views
1

我有一個簡單的類像下面這樣:匹配的文件路徑字符串的第一部分

class Record 
{ 
    public Record(string fp1, string fp2, string fp3) 
    { 
     Filepath1 = fp1; 
     Filepath2 = fp2; 
     Filepath3 = fp3; 
    } 

    public string Filepath1 { get; private set; } 
    public string Filepath2 { get; private set; } 
    public string Filepath3 { get; private set; } 
} 

每個文件路徑將是非常相似的(並且很長),並只向的最後幾個字符不同文件路徑。

現在,我想有這些記錄的幾千在內存中,我想這些記錄使用最多的RAM量較小。所以,我試圖想辦法來優化內存使用情況,這裏是我想出了一個解決辦法:

class Record 
{ 
    private string _baseFilepath; 
    private string _fp1; 
    private string _fp2; 
    private string _fp3; 
    public Record(string fp1, string fp2, string fp3) 
    { 
     _baseFilepath = /*get common first part of filepaths*/; 
     _fp1 = /*last part of fp1*/; 
     _fp2 = /*last part of fp2*/; 
     _fp3 = /*last part of fp3*/; 
    } 

    public string Filepath1 
    { 
     get { return _baseFilepath + _fp1; } 
    } 

    public string Filepath2 
    { 
     get { return _baseFilepath + _fp2; } 
    } 

    public string Filepath3 
    { 
     get { return _baseFilepath + _fp3; } 
    } 
} 

你可以看到,我可以節省大量的內存,特別是很長的文件路徑只有在最後幾個字符是不同的。問題是,是否有一種簡單的方法來獲得文件路徑的第一部分?

編輯: ,可能有多達70萬條記錄在內存中,實際生產類有幾個文件路徑。我試圖讓應用盡可能輕量化,同時爲了簡單起見,儘量保持優化非常簡單。

+1

萬條記錄將佔用一兆字節左右。您是否在嚴格受限的硬件上運行? – 2011-05-03 22:24:12

+0

它實際上取決於。這是針對服務器應用程序的,每個連接到服務器的用戶都可能導致4000條記錄在內存中。 – Phil 2011-05-03 22:30:22

+0

哦,這不是我的製作課,只是一個例子。在現實生活中將會有更多的文件路徑。 – Phil 2011-05-03 22:32:29

回答

4

這將做到這一點:

public static string GetCommonStart(string fp1, string fp2, string fp3) 
{ 
    int idx = 0; 
    int minLength = Math.Min(Math.Min(fp1.Length, fp2.Length), fp3.Length); 
    while (idx < minLength && fp1[idx] == fp2[idx] && fp2[idx] == fp3[idx]) 
     idx++; 
    return fp1.Substring(0, idx); 
} 
+0

不錯,我會添加一個檢查以確保你不會超過最短字符串的長度。 ex'c:\ 1.jpg'和'c:\ 1.jpg.jpg'會出錯。就像那樣編輯。 :) – 2011-05-03 22:30:43

+0

@Biff:已經在:-) – BrokenGlass 2011-05-03 22:32:41

1

您可以使用這樣的事情,如果這個動作是不是性能關鍵你:

public static class StringExtensions 
{ 
    public static string GetCommonPrefix(string a, string b) 
    { 
     int commonPrefixLength = 0; 
     int minimumLength = Math.Min(a.Length, b.Length); 

     for (int i = 0; i < minimumLength; i++) 
     { 
      if (a[i] == b[i]) 
      { 
       commonPrefixLength++; 
      } 
     } 

     return a.Substring(0, commonPrefixLength); 
    } 

    public static string GetCommonPrefix(params string[] strings) 
    { 
     return strings.Aggregate(GetCommonPrefix); 
    } 
} 
1

請考慮這個補充答案,提供替代建議,而不是直接回答您的問題(已提供)。

如果可能,我會在第一個可能的機會&將這些文件路徑分爲basesuffix,然後通過整個系統以這種方式傳遞。

這如果

  • 你自己在你的系統
  • 你是從已知的&有限集合地點

你也只會讀取文件生成這些文件路徑,地方適用一組base文件路徑,以及那些base值的每一次引用Filepath,也包含了自己suffix價值。

根據base文件路徑的數量&如何確定它們,這將顯着提高內存效率。您當前的解決方案提供了最佳情況下的三分之一內存使用量(每個三個文件路徑最佳優化爲一個文件路徑)。在整個應用程序中以一致的方式存儲此對象(filepath)也是有意義的。