如何以最短且有效的方法将各种字符串连接到字符串中。目前我正在以下列方式做事
string str1 = string.Format(BitConverter
.ToString(pass_packet, local_index + 511, 1) +
BitConverter.ToString(pass_packet, local_index + 510, 1) +
BitConverter.ToString(pass_packet, local_index + 509, 1) +
BitConverter.ToString(pass_packet, local_index + 508, 1) +
... + BitConverter.ToString(pass_packet, local_index + 400, 1));
答案 0 :(得分:5)
考虑到测试数据,我认为你根本不需要连接。获取字节数组,反转它们然后通过一个BitConverter.ToString调用它!
class Program
{
static int ITERATIONS = 100000;
static void Main(string[] args)
{
var pass_packet = Enumerable.Range(0, 1024).Select(i => (byte)i).ToArray();
int local_index = 5;
var sw = Stopwatch.StartNew();
var result = StringBuilderTEST(pass_packet, local_index);
Console.WriteLine(result + " in {0}ms", sw.ElapsedMilliseconds);
//second option
sw.Restart();
var result2 = ArrayReversalTEST(pass_packet, local_index);
Console.WriteLine(result2 + " in {0}ms", sw.ElapsedMilliseconds);
sw.Restart();
var result3 = ArrayReversal2TEST(pass_packet, local_index);
Console.WriteLine(result3 + " in {0}ms", sw.ElapsedMilliseconds);
sw.Restart();
var result4 = StupidlyFastTEST(pass_packet, local_index);
Console.WriteLine(result4 + " in {0}ms", sw.ElapsedMilliseconds);
Console.WriteLine("Results are equal? " + (result == result2 && result == result3 && result == result4));
Console.ReadLine();
}
private static string StringBuilderTEST(byte[] pass_packet, int local_index)
{
string result = null;
for (int b = 0; b < ITERATIONS; b++)
{
var sb = new StringBuilder();
for (int i = 511; i >= 400; i--)
sb.Append(BitConverter.ToString(pass_packet, local_index + i, 1));
result = sb.ToString();
}
return result;
}
private static string ArrayReversalTEST(byte[] pass_packet, int local_index)
{
string result = null;
for (int b = 0; b < ITERATIONS; b++)
{
var selectedData = pass_packet.Skip(400 + local_index).Take(112).Reverse().ToArray();
result = BitConverter.ToString(selectedData).Replace("-", "");
}
return result;
}
private static string ArrayReversal2TEST(byte[] pass_packet, int local_index)
{
string result = null;
for (int b = 0; b < ITERATIONS; b++)
{
var tempArray = new byte[112];
Array.Copy(pass_packet, 400 + local_index, tempArray, 0, 112);
Array.Reverse(tempArray);
result = BitConverter.ToString(tempArray).Replace("-", "");
}
return result;
}
private static string StupidlyFastTEST(byte[] pass_packet, int local_index)
{
string result = null;
string hex = "0123456789ABCDEF";
for (int it = 0; it < ITERATIONS; it++)
{
var tempArray = new char[112 * 2];
int tempArrayIndex = 0;
for (int i = 511; i >= 400; i--)
{
var b = pass_packet[local_index + i];
tempArray[tempArrayIndex++] = hex[b >> 4];
tempArray[tempArrayIndex++] = hex[b & 0x0F];
}
result = new string(tempArray);
}
return result;
}
}
结果:
Test 1 in 478ms
Test 2 in 1134ms
Test 3 in 516ms
Test 4 in 114ms
Results are equal? True
正如您所看到的,我重写代码的前两次尝试效率不高 - 特别是考虑到创建和维护所需的额外时间。然而,一些快速测试表明,这是由于String.Replace需要使结果相同 - 因为默认转换器在数组中的每个字节对之间放置' - ',原始算法由于单字节长度而未看到
//Without String.Replace in tests 2 and 3
Test 1 in 475ms
Test 2 in 704ms
Test 3 in 92ms
Test 4 in 115ms
Results are equal? False
正如您在原始性能方面所看到的,Test3速度最快 - 尽管默认输出在每个字节之间包含' - '。
Test4用快速手动版本替换转换器 - 消除了字节分隔符 - 并且是原始结果的最快版本。我怀疑缓存临时数组,并替换分区&amp;模数数 *使用更大的256元素十六进制数组会大大加快速度,但鉴于这一点已被证明将停在这里。
*编辑,用位操作替换除法和模数以显着加速。
答案 1 :(得分:2)
我会这样做:
StringBuilder sb = new StringBuilder();
for (int i = 511; i >= 400; --i)
sb.Append(BitConverter.ToString(pass_packet, local_index + i, 1));
string str1 = sb.ToString();
答案 2 :(得分:0)
string.Concat
是你的朋友。
string.Concat(BitConverter.ToString(pass_packet, local_index + 511, 1),
BitConverter.ToString(pass_packet, local_index + 510, 1),
BitConverter.ToString(pass_packet, local_index + 509, 1),
BitConverter.ToString(pass_packet, local_index + 508, 1),
BitConverter.ToString(pass_packet, local_index + 400, 1));
有两个有趣的重载:string.Concat(params Object[] args)和
string.Concat(params string[] values)。两者都接受一个可变长度的参数(正如我所做的那样)或一个正确类型的数组。甚至有超载接受IEnumerable<string>
或IEnumerable<T>
,其中T
是任何一种类型。
答案 3 :(得分:0)
这有点棘手,但我认为这可以完成工作。
string myString = new String(Enumerable.Range(400,111).SelectMany(x => BitConverter.ToString(pass_packet, x + 509, 1)).ToArray());