C# - 10진수 숫자를 담은 문자열을 숫자로 변환하는 방법
아래와 같은 질문이 있군요.
아스키로 구성된 바이트를 long으로 변환 문의
; https://www.sysnet.pe.kr/3/0/5664
정리해 보면, 숫자를 "문자열"로 가지고 있는 데이터를 다시 숫자로 변환하고 싶은 건데요, 가령 "0000000123" 문자열이 보관된 byte 배열을,
byte [] bytes = /* 소켓 Receive로 받은 바이트 배열 */ Encoding.ASCII.GetBytes("0000000123");
숫자 123으로 변환하고 싶은 것입니다.
string tmp = Encoding.ASCII.GetString(bytes);
long myint = Convert.ToInt64(tmp);
질문자는 위에 대한 코드보다 더 빠른 것을 원하는 건데요, 사실 이런 경우, BCL에서 제공하는 메서드를 다루는 것이 최적화가 잘 된 코드라서 대부분은 충분히 빠르므로 그냥 쓰셔도 좋습니다.
굳이, 아주 미세하게 빠른 속도를 원한다면 GetString 절차를 생략하고 곧바로 바이트 배열로부터 숫자를 바꿀 수 있을 텐데요, 대충 다음과 같은 식으로 만들 수 있습니다.
private static long ConvertToLong(byte[] bytes)
{
long n = 1;
long result = 0;
for (int i = bytes.Length - 1; i >= 0; i --)
{
result = result + (bytes[i] - '0') * n;
n *= 10;
}
return result;
}
성능 측정을 해보면 딱히 "감동적인" 수준으로 빠르지는 않습니다. 어쨌든 이렇게 테스트 코드를 구성해서,
using System.Diagnostics;
using System.Text;
internal class Program
{
static void Main(string[] args)
{
Action<int, string, Func<byte[], long>, byte[]> action = (loopCount, title, work, arg) =>
{
Stopwatch st = new Stopwatch();
st.Start();
Random rand = new Random(Environment.TickCount);
for (int i = 0; i < loopCount; i++)
{
work(arg);
}
st.Stop();
Console.WriteLine(title + " : " + st.ElapsedMilliseconds);
};
byte[] buf = Encoding.ASCII.GetBytes("1000000123");
action(1, "touch-JIT", ConvertNormal, buf);
action(1, "touch-JIT", ConvertToLong, buf);
Console.WriteLine();
action(1000000, "ConvertNormal", ConvertNormal, buf);
action(1000000, "ConvertToLong", ConvertToLong, buf);
}
private static long ConvertNormal(byte[] bytes)
{
string tmp = Encoding.ASCII.GetString(bytes);
return Convert.ToInt64(tmp);
}
// ...[생략 ConvertToLong]...
}
실행하면 이런 결과가 나옵니다.
ConvertNormal : 36
ConvertToLong : 12
수치상으로 3배 빨라지긴 했는데, 백만 번 수행한 속도 차이이기 때문에 웬만한 고성능을 요구하는 경우가 아니라면 차이는 미미합니다. 게다가, 저렇게나 성능이 요구되는 시스템이라면 애당초 서버 측에 "숫자 문자열"이 아닌, "숫자"로 데이터를 정정해서 보내달라고 하는 편이 더 효과를 거둘 수 있습니다.
(
첨부 파일은 이 글의 예제 코드를 포함합니다.)
[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]