2017-04-01 113 views
1

用最小的分配量向StringBuilder附加整數。有更快的方法嗎?最快的StringBuilder整數的追加

public static void AppendInvariant(this StringBuilder builder, int value) 
    { 
     // Deal with negative numbers 
     if (value < 0) 
     { 
      builder.Append('-'); 
      uint uint_value = uint.MaxValue - ((uint)value) + 1; //< This is to deal with Int32.MinValue 
      AppendInvariant(builder, uint_value); 
     } 
     else 
     { 
      AppendInvariant(builder, (uint)value); 
     } 
    } 

    public static void AppendInvariant(this StringBuilder builder, uint value) 
    { 
     if (value == 0) 
     { 
      builder.Append('0'); 
      return; 
     } 

     // Pad out space for writing. 
     int length = UintLength(value); 
     builder.Append('0', length); 
     length = builder.Length; 

     uint tmp_value; 
     do 
     { 
      tmp_value = value; 
      value /= 10; 
      builder[--length] = (char)('0' + (tmp_value - value * 10)); 
     } while (value > 0); 
    } 

    private static int UintLength(uint i) 
    { 
     if (i < 100000) 
     { 
      if (i < 10) return 1; 
      if (i < 100) return 2; 
      if (i < 1000) return 3; 
      if (i < 10000) return 4; 
      return 5; 
     } 
     else 
     { 
      if (i < 1000000) return 6; 
      if (i < 10000000) return 7; 
      if (i < 100000000) return 8; 
      if (i < 1000000000) return 9; 
      return 10; 
     } 
    } 
+1

'助洗劑[ - 長度] =(char)的( '0' +(tmp_value - 值* 10));' 沒有分配,你說什麼? :) – john

+1

@john是的你是對的,會有StringBuilder緩衝區分配,但我會接受:) –

回答

2

以下實現速度快大約2倍。

它確實,通過通過使用少量100元前分配的字符串表最小化StringBuilder呼叫

private static readonly string[] UIntPairStrings = 
    Enumerable.Range(0, 100).Select(n => n.ToString("00")).ToArray(); 

並且還通過從較高到較低的處理在2位對輸入值分割數最小化(以彌補缺乏存儲)。這種方式的操作不超過5個電話號碼。

private static readonly uint[] UIntPairScales = { 100000000, 1000000, 10000, 100 }; 

public static void AppendInvariant(this StringBuilder builder, uint value) 
{ 
    bool next = false; 
    foreach (var scale in UIntPairScales) 
    { 
     if (value >= scale) 
     { 
      uint pair = value/scale; 
      if (!next && pair < 10) 
       builder.Append((char)('0' + pair)); 
      else 
       builder.Append(UIntPairStrings[pair]); 
      value -= pair * scale; 
      next = true; 
     } 
     else if (next) 
     { 
      builder.Append("00"); 
     } 
    } 
    if (!next && value < 10) 
     builder.Append((char)('0' + value)); 
    else 
     builder.Append(UIntPairStrings[value]); 
}