c# - 添加字节到字节数组方法优化
问题描述
我有一个包含超过 200 000 个字符串的列表(每个值在十六进制中看起来像“0x01”)。我正在做的是循环列表中的每个值并将该字符串值转换为一个字节,然后将其添加到字节数组中。我遇到了一个问题 - 它持续时间太长(例如 200 000 个字符串持续 16 秒)。我在互联网上发现了这种方法,它向现有字节数组添加了一个字节,但这种方法似乎很慢:
private byte[] addByteToArray(byte[] bArray, byte newByte)
{
byte[] newArray = new byte[bArray.Length + 1];
bArray.CopyTo(newArray, 1);
newArray[0] = newByte;
return newArray;
}
你知道如何在几毫秒而不是几秒内让这个方法更快吗?提前感谢您的想法!
解决方案
我有一个包含超过 200 000 个字符串的列表(每个值在十六进制中看起来像“0x01”)。我正在做的是循环列表中的每个值并将该字符串值转换为一个字节,然后将其添加到字节数组中
所以你有这个:
List<String> listOfHexBytes = new List<String>() { "0x01", "0x02", "0x03", ... };
你想得到Byte[]
吗?
不幸的是,.NET 没有简单的内置方法来解析 C 样式的十六进制数,所以这里有一个快速的方法(通过避免子字符串来避免 GC 堆分配):
static class Base16
{
public static Byte GetNibble( Char hexDigit )
{
if( hexDigit >= 48 && hexDigit <= 57 ) return (Byte)( hexDigit - 48 ); // 0-9
if( hexDigit >= 65 && hexDigit <= 90 ) return (Byte)( 10 + ( hexDigit - 65 ) ); // A-F
if( hexDigit >= 97 && hexDigit <= 122 ) return (Byte)( 10 + ( hexDigit - 65 ) ); // a-f
throw new ArgumentOutOfRangeException( nameof(hexDigit), hexDigit, "Value is not a hexadecimal digit character." );
}
public static Byte ParseCStyleByte( String s )
{
if( s.Length == 4 && s[0] == '0' && s[1] == 'x' )
{
Char h = s[2]; // high nibble
Char l = s[3]; // low nibble
Byte hb = GetNibble( h );
Byte lb = GetNibble( h );
return ( hb << 4 ) | lb;
}
else
{
throw new FormatException( "Value \"" + s + "\" is not a C-style byte." );
}
}
}
像这样使用:
Byte[] asByteArray = listOfHexBytes
.Select( Base16.ParseCStyleByte )
.ToArray();
虽然这会导致两个数组副本ToArray
在输入具有已知长度时不会优化(Linq 有一些愚蠢的设计问题......),但这样做也可以:
Byte[] output = new Byte[ listOfHexBytes.Count ];
for( Int32 i = 0; i < output.Length; i++ )
{
output[i] = Base16.ParseCStyleByte( listOfHexBytes[i] );
}
推荐阅读
- javascript - 当滚动命中位置时显示元素
- laravel - Laravel - 在社交名流 Azure AD 登录中没有为应用程序注册回复地址
- ssl - HTTPS 配置后 Spinnaker 服务未启动
- c# - luis 模型和团队对同一句话的不同意图,如何解决?
- python - Holoviews 图表在组合和输出时共享轴
- entity - 放大/缩小时如何在铯中保持与椭圆实体相同的像素大小(如点)
- jenkins - 詹金斯。在执行管道之前创建属性文件
- java - 如何将静态变量调用为非静态方法,即我需要调用maxId变量来插入方法
- java - MIFARE卡1k是否可以锁定命令,保护克隆或不可被其他应用程序擦除
- css - 如何在 Vue.js 项目中使用自动更正设置 css linting