我正在将文件读入byte[] buffer
。该文件包含许多UTF-16字符串(数百万),格式如下:
我需要对文件中的所有字符串执行标准字符串操作,例如:IndexOf
,EndsWith
和StartsWith
,StringComparison.OrdinalIgnoreCase
和StringComparison.Ordinal
现在我的代码首先将每个字符串从字节数组转换为System.String
类型。我发现以下代码是最有效的:
// position/length validation removed to minimize the code
string result;
byte charLength = _buffer[_bufferI++];
int byteLength = charLength * 2;
fixed (byte* pBuffer = &_buffer[_bufferI])
{
result = new string((char*)pBuffer, 0, charLength);
}
_bufferI += byteLength;
return result;
仍然,new string(char*, int, int)
它非常慢,因为它为每个字符串执行不必要的复制 。
Profiler表示其System.String.wstrcpy(char*,char*,int32)
执行缓慢。
我需要一种方法来执行字符串操作而不复制每个字符串的字节。
有没有办法直接对字节数组执行字符串操作?
有没有办法创建新字符串而不用复制其字节?
答案 0 :(得分:2)
不,如果不复制字符数据,则无法创建字符串。
String
对象将字符串的元数据(Length,et.c。)存储在与字符数据相同的内存区域中,因此您无法将字符数据保留在字节数组中并假装它是String
对象。
您可以尝试其他方法从字节数据构造字符串,并查看其中是否有任何开销较少,如Encoding.UTF16.GetString
。
如果您使用的是指针,则可以尝试一次获取多个字符串,这样就不必为每个字符串修复缓冲区。
答案 1 :(得分:0)
您可以使用Encoding.UTF16使用StreamReader读取文件,因此您之间没有“字节开销”:
using (StreamReader sr = new StreamReader(filename, Encoding.UTF16))
{
string line;
while ((line = sr.ReadLine()) != null)
{
//Your Code
}
}
答案 2 :(得分:0)
您可以在字节数组上创建扩展方法,以直接在字节数组上处理大多数字符串操作,从而避免转换成本。不确定你执行的所有字符串操作,所以不确定是否所有这些操作都可以通过这种方式完成。