字节/字符缓冲区为长和/或双精度
本文关键字:双精度 字符 缓冲区 字节 | 更新日期: 2023-09-27 17:54:20
在我的代码中,我需要将整数的字符串表示形式转换为long
和double
值。
字符串表示为字节数组(byte[]
)。例如,对于数字12345
字符串表示为{ 49, 50, 51, 52, 53 }
目前,我使用以下明显的代码转换为long
(和几乎相同的代码转换为double
)
private long bytesToIntValue()
{
string s = System.Text.Encoding.GetEncoding("Latin1").GetString(bytes);
return long.Parse(s, CultureInfo.InvariantCulture);
}
这段代码按预期工作,但是在我的例子中我想要更好的。这是因为目前我必须先将字节转换为字符串。
在我的例子中,bytesToIntValue()
被调用了大约1200万次,大约25%的内存分配是在这个方法中进行的。
当然,我想优化这部分。我想执行转换没有中间字符串(+ speed, - allocation)。
你有什么建议吗?如何在没有中间字符串的情况下执行转换?是否有更快的方法来执行转换?
编辑:我正在处理的字节数组总是包含ascii编码的数据。数字可以是负数。对于双精度值,允许使用指数格式。不允许十六进制整数
如何在没有中间字符串的情况下执行转换?
你可以很容易地将每个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(例如),那么它肯定会做错误的事情。
还要注意,这不会执行任何类型的长度验证或溢出检查…它不能处理负数。如果你想的话,你可以添加所有这些,但我们对你的需求了解不够,不知道是否值得添加这些复杂性。
我不确定是否有简单的方法可以做到这一点,请注意,它不会与其他编码工作,测试显示在我的电脑上,这是只有3倍快(我不认为它值得)。
代码+ test:
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;
}
}
最后,我创建了c#版本的strol
函数。该函数随CRT自带,CRT的源代码随Visual Studio自带。
结果方法几乎与@Jon Skeet在他的回答中提供的代码相同,但也包含一些溢出检查。
在我的例子中,所有的改变都被证明在速度和内存方面非常有用。