2010-03-26 94 views
1

我正在重新編寫一個任務,使它完全免費分配。目標是在應用程序的啓動階段完成後有0個集合。Ascii Bytes Array To Int32或Double

此前,有很多這樣的電話:

Int32 foo = Int32.Parse(ASCIIEncoding.ASCII.GetString(bytes, start, length)); 

我相信這是分配的字符串。我無法找到自動執行相同操作的C#庫函數。我查看了BitConverter類,但是看起來只有當Int32使用表示它的實際字節進行編碼時纔是如此。在這裏,我有一個表示代表Int32的Ascii字符的字節數組。

這裏就是我所做的

public static Int32 AsciiBytesToInt32(byte[] bytes, int start, int length) 
{ 
    Int32 Temp = 0; 
    Int32 Result = 0; 
    Int32 j = 1; 

    for (int i = start + length - 1; i >= start; i--) 
    { 
      Temp = ((Int32)bytes[i]) - 48; 

      if (Temp < 0 || Temp > 9) 
      { 
       throw new Exception("Bytes In AsciiBytesToInt32 Are Not An Int32"); 
      } 

      Result += Temp * j; 
      j *= 10; 
    } 

    return Result; 
} 

有誰知道一個C#庫函數在一個更優化的方式,已經這樣做了嗎?或者是讓上述運行速度更快的一種改進(可能會在白天被稱爲數百萬次)。謝謝!

+3

如果有一件事使得託管代碼優於傳統代碼,那麼分配內存的成本非常低。有意避免它就像吹你的左腳去參加奧運比賽。 – 2010-03-26 12:26:54

+0

分配內存很便宜;垃圾收集不是。創建大量的垃圾最終會將相對短暫的對象推到Gen2堆上,這通常是值得避免的。 – Gabe 2010-03-26 12:54:21

+0

同意。我們正在努力減少收集。我們肯定會看到一些Gen2收藏需要長達100ms。這些短命的字符串並不是一個很大的問題,我猜,它們應該很快收集起來。但他們並不難去除。如果我們只說:在應用程序的連續運行階段沒有分配,它可以更容易地追蹤真正的重大分配來自哪裏。 – 2010-03-26 13:24:17

回答

5

每天數百萬次不應該是一個問題 - 我希望能夠每秒運行數十萬次。就個人而言,我會重寫上面的內容,只在循環中聲明「temp」(並且除掉Pascal-cases局部變量名稱 - urgh),但它應該沒問題。

int digit = bytes[i] - '0'; 

這不相同,您

Temp = ((Int32)bytes[i]) - 48; 

線,但在一個更簡單的方法(IMO):

的代碼會更直接的理解爲是。他們應該表現完全一樣的方式。

一般來說,試圖編寫C#而沒有任何分配是非常苛刻的,並且與語言和框架的設計方式相抵觸。你是否相信這是其實一個合理的要求?無可否認,我聽說過一些遊戲是用託管代碼編寫的,但它確實有點奇怪。

當然,你要分配一個異常,如果字節都不合適......

編輯:請注意,您的代碼不允許負數。可以嗎?

+1

他也不處理溢出。 – Gabe 2010-03-26 12:58:00

+0

感謝您的回覆。 關於底片和溢出的優點。這些整數應該是相當小的,但否定可能是一個問題。 – 2010-03-26 13:20:59

+0

我不應該說沒有分配。我的意思是我們正試圖在應用程序的啓動階段預先分配幾乎所有的東西。 這是一個應用程序,其中Gen2集合的100ms凍結可能會產生影響,因此我們試圖按照此處列出的設計實踐進行操作: http://www.microsoft.com/downloads/details.aspx ?displaylang = EN&FAMILYID = 4215ab9e-4181-4526-823b-d364448188b2 – 2010-03-26 13:21:44