2013-01-19 3 views
0

내 코드에서 정수의 문자열 표현을 longdouble 값으로 변환해야합니다.long/double 버퍼에 대한 바이트/char 버퍼

문자열 표현은 바이트 배열 (byte[])입니다. 예를 들어, 숫자 12345 캐릭터 라인 표현을 위해 나는 long로 변환 명백한 코드를 다음 (그리고 double로 변환 거의 동일한 코드)이 코드는 예상 작품으로

private long bytesToIntValue() 
{ 
    string s = System.Text.Encoding.GetEncoding("Latin1").GetString(bytes); 
    return long.Parse(s, CultureInfo.InvariantCulture); 
} 

사용하여 현재 { 49, 50, 51, 52, 53 }

입니다, 하지만 내 경우에 나는 더 나은 것을 원한다. 그것은 현재 바이트를 문자열로 먼저 변환해야하기 때문입니다.

필자의 경우 bytesToIntValue()은 약 1,200 만 번 호출되며이 방법에서는 전체 메모리 할당의 약 25 %가 수행됩니다.

물론이 부분을 최적화하고 싶습니다. 중간 문자열없이 변환을 수행하려고합니다 (+ 속도, - 할당).

무엇을 권하고 싶습니까? 중간 문자열없이 변환을 수행하려면 어떻게해야합니까? 전환을 수행하는 더 빠른 방법이 있습니까?

편집 : 나는 취급하고

바이트 배열은 항상 ASCII로 인코딩 된 데이터를 포함하고 있습니다. 숫자는 음수 일 수 있습니다. double 값의 경우 지수 형식이 허용됩니다. 16 진수는 허용되지 않습니다.

답변

0

결국, 나는 strol 함수의 C# 버전을 만들었습니다. 이 함수는 CRT와 함께 제공되며 CRT 소스 코드는 Visual Studio와 함께 제공됩니다.

결과 메서드는 @Jon Skeet이 제공 한 답변과 거의 동일하지만 오버플로 검사도 포함되어 있습니다.

내 경우에는 모든 변경 사항이 속도와 메모리면에서 매우 유용하다는 것이 입증되었습니다.

1

쉽게 할 수있는 방법이 확실하지 않습니다. 다른 인코딩에서는 작동하지 않습니다. 내 컴퓨터에 표시된 테스트는 3 배 빨랐습니다 (나는 그렇지 않습니다. 그것을 가치가 있다고 생각하십시오).

코드 + 시험 :

class MainClass 
{ 
    public static void Main(string[] args) 
    { 
     string str = "12341234"; 
     byte[] buffer = Encoding.ASCII.GetBytes(str); 

     Stopwatch sw = Stopwatch.StartNew(); 
     for(int i = 0; i < 1000000 ;i ++) 
     { 
      long val = BufferToLong.GetValue(buffer); 
     } 
     Console.WriteLine (sw.ElapsedMilliseconds); 
     sw.Restart(); 
     for (int i = 0 ; i < 1000000 ; i++) 
     { 
      string valStr = Encoding.ASCII.GetString(buffer); 
      long val = long.Parse(valStr); 
     } 
     Console.WriteLine (sw.ElapsedMilliseconds); 
    } 
} 

static class BufferToLong 
{ 

    public static long GetValue(Byte[] buffer) { 

     long number = 0; 

     foreach (byte currentByte in buffer) { 

      char currentChar = (char)currentByte; 
      int currentDigit = currentChar - '0'; 

      number *= 10 ; 
      number += currentDigit; 

     } 

     return number; 
    } 

} 
+0

해답을 알려줘서 고맙지 만 질문은 '길다. 속도가 빠름'이 아니다. 그리고 그것이 있었다고하더라도, 3 배 속도 증가가 가치가있는 것입니다, imho. 어떤 프로세스가 3 시간 걸리는지 생각해보십시오 .-) – Bobrovsky

+0

더 많은 서버/코어로 작업을 확장 할 수있을 것입니다. 때때로 가독성/유지 관리 성은 성능 이상의 가치가 있습니다. 또한, 나는 '길다. 빠르다'의 속도에 대해서가 아니라 'Byte []'를 가져 와서 'long'으로 파싱하는 전 과정을 말하고있다. –

3

가 어떻게 중간 문자열없이 변환을 수행 할 수 있습니까?

그럼 당신은 쉽게 각 byte char로 변환 할 수 있습니다. 예를 들어 - 검증되지 않은 :

private static long ConvertAsciiBytesToInt32(byte[] bytes) 
{ 
    long value = 0; 
    foreach (byte b in bytes) 
    { 
     value *= 10L; 
     char c = b; // Implicit conversion; effectively ISO-8859-1 
     if (c < '0' || c > '9') 
     { 
      throw new ArgumentException("Bytes contains non-digit: " + c); 
     } 
     value += (c - '0'); 
    } 
    return value; 
} 

참고이 정말 하지는 ASCII (또는 호환)의 가정 것을 - 당신의 바이트 배열이 실제로 UTF-16 (예를 들어) 인 경우 다음 잘못된 일을 확실히 할 것이다.

또한 길이 검사 또는 오버플로 검사를 수행하지 않으며 음수를 처리하지 않습니다. 원하는 경우이 모든 것을 추가 할 수 있지만 복잡성을 추가할만한 가치가 있는지 알기 위해 요구 사항을 충분히 모릅니다.

+0

고맙습니다. 질문을 업데이트했습니다. – Bobrovsky

관련 문제