c#以更短,更有效的方式连接字符串

pra*_*tom 0 c# string string-concatenation

如何以最短和最有效的方法将各种字符串连接到字符串中.目前我正在以下列方式进行

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));
Run Code Online (Sandbox Code Playgroud)

NPS*_*000 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

结果:

Test 1 in 478ms
Test 2 in 1134ms
Test 3 in 516ms
Test 4 in 114ms
Results are equal?  True
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我重写代码的前两次尝试效率不高 - 特别是考虑到创建和维护所需的额外时间.然而,一些快速测试显示,这是由于使结果相同所需的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
Run Code Online (Sandbox Code Playgroud)

正如您在原始性能术语中看到的那样,Test3速度最快 - 尽管默认输出在每个字节之间包含' - '.

Test4用快速手动版本替换了转换器 - 消除了字节分隔符 - 并且是原始结果的最快版本.我怀疑缓存临时数组,并用更大的256元素十六进制数组替换divisions&modulus数学*会大大加快它的速度,但鉴于这一点已被证明将停在这里.

*通过位操作编辑,替换分区和模数,以实现显着的加速.