2013-08-06 22 views
2

多個唯一的字符串我的項目,我必須生成唯一字符串列表。 一切工作正常,但我的問題是,它在最後是非常緩慢。 我已經使用並行循環試過,但我發現我ConcurrentBag<T>,我用它,也慢。 現在我使用一個簡單的for循環和List<T>,現在快一點點的,也很慢。生成C#

這裏是我的代碼:

private List<string> Generate(int start, int end, bool allowDupes) 
    { 
     var list = new List<string>(); 
     var generator = new StringGenerator(LowerCase, UpperCase, Digits, NumberOfCharacters); 
     for (var i = start; i < end; i++) 
     { 
      StringBuilder sb; 
      while (true) 
      { 
       sb = new StringBuilder(); 
       for (var j = 0; j < NumberOfSegments; j++) 
       { 
        sb.Append(generator.GenerateRandomString()); 
        if (j < NumberOfSegments - 1) 
        { 
         sb.Append(Delimiter); 
        } 
       } 
       if (!allowDupes) 
       { 
        if (list.Contains(sb.ToString())) 
        { 
         continue; 
        } 
       } 
       break; 
      } 
      list.Add(sb.ToString()); 
      GeneratedStringCount = i + 1; 
     } 
     return new List<string>(list); 
    } 

我也跟我的老師,他會使用相同的算法生成這些字符串。 你知道更好的解決方案嗎? (在StringGeneratorGenerateRandomString()方法簡單,不消耗過多的表現。list.Contains(xy)是消耗資源的很多。[在Visual Studio性能分析])

+1

什麼開始和結束點?它看起來像你想要多少簡單的計數。爲什麼'返回新的List(list)'而不是'return list'? – Jonesopolis

+0

這些字符串的內容有什麼限制? –

+0

嘗試使用HashSet 而不是列表如果需要大量字符串,這應該會提高性能 –

回答

2

List.Contains是緩慢的。改爲使用HashSet

private List<string> Generate(int start, int end, bool allowDupes) 
{ 
    var strings = new HashSet<string>(); 
    var list = new List<string>(); 
    var generator = new StringGenerator(LowerCase, UpperCase, Digits, NumberOfCharacters); 
    for (var i = start; i < end; i++) 
    { 
     while (true) 
     { 
      string randomString = GetRandomString(); 
      if (allowDupes || strings.Add(randomString)) 
      { 
       list.Add(randomString); 
       break; 
      } 
     } 
     GeneratedStringCount = i + 1; 
    } 
    return new List<string>(list); 
} 

private string GetRandomString() 
{ 
    var segments = Enumerable.Range(1, NumberOfSegments) 
     .Select(_ => generator.GenerateRandomString()); 
    var result = string.Join(Delimeter, segments); 
    return result; 
} 

這仍然有性能下降的機會,但你可以彌補與智能GenerateRandomString功能。

+0

謝謝,現在它快了很多。 (對於1百萬字符~32秒)我會嘗試優化我的'GenerateRandomString()'方法。 –

0
public static String GenerateEightCode(int codeLenght, Boolean isCaseSensitive) 
    { 
     char[] chars = GetCharsForCode(isCaseSensitive); 
     byte[] data = new byte[1]; 
     RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider(); 
     crypto.GetNonZeroBytes(data); 
     data = new byte[codeLenght]; 
     crypto.GetNonZeroBytes(data); 
     StringBuilder sb = new StringBuilder(codeLenght); 
     foreach (byte b in data) 
     { 
      sb.Append(chars[b % (chars.Length)]); 
     } 

     string key = sb.ToString(); 

     if (codeLenght == 8) 
      key = key.Substring(0, 4) + "-" + key.Substring(4, 4); 
     else if (codeLenght == 16) 
      key = key.Substring(0, 4) + "-" + key.Substring(4, 4) + "-" + key.Substring(8, 4) + "-" + key.Substring(12, 4); 

     return key.ToString(); 
    } 

    private static char[] GetCharsForCode(Boolean isCaseSensitive) 
    { 
     // all - abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 
     char[] chars = new char[58]; 
     if (isCaseSensitive) 
     { 
      chars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ123456789".ToCharArray();//počet unikátních kombinací 4 - 424 270, 8 - 1 916 797 311, 16 - 7.99601828013E+13 
     } 
     else 
     { 
      chars = new char[35]; 
      chars = "ABCDEFGHIJKLMNPQRSTUVWXYZ123456789".ToCharArray();//počet unikátních kombinací 4 - 52 360, 8 - 23 535 820, 16 - 4 059 928 950 
     } 

     return chars; 
    }