c# - 比 String.Replace() 更快

标签 c# performance

有没有比这样做更快的其他方法?

private void EscapeStringSequence(ref string data)
{
    data = data.Replace("\\", "\\\\"); // Backslash
    data = data.Replace("\r", "\\r");  // Carriage return
    data = data.Replace("\n", "\\n");  // New Line
    data = data.Replace("\a", "\\a");  // Vertical tab
    data = data.Replace("\b", "\\b");  // Backspace
    data = data.Replace("\f", "\\f");  // Formfeed
    data = data.Replace("\t", "\\t");  // Horizontal tab
    data = data.Replace("\v", "\\v");  // Vertical tab
    data = data.Replace("\"", "\\\""); // Double quotation mark
    data = data.Replace("'", "\\'");   // Single quotation mark
}

-- 已编辑(添加解释)--
问题 1:您需要加快速度的原因是什么?会造成大问题吗?
此部分用于此项目:http://mysqlbackuprestore.codeplex.com/
我要将许多不同长度的字符串重复循环到这个函数中。完成数百万行的整个过程大约需要 6-15 秒。还有其他部分也参与其中。我正在努力加快每个部分的速度。

Q2:现在有多慢?
好的,我会记录使用的确切时间并将其发布在这里。我稍后再来。 (明天公布结果)

更新 29-06-2012
我已经运行测试。这是结果:

速度测试:String.Replace() - 以毫秒为单位
测试 1:26749.7531 毫秒
测试 2:27063.438 毫秒
测试 3:27753.8884 毫秒
平均:27189.0265 毫秒
速度:100%

速度测试:Foreach Char and Append - 以毫秒为单位
测试 1:8468.4547 毫秒
测试 2:8348.8527 毫秒
测试 3:8353.6476 毫秒
平均:8390.3183 毫秒
速度:224% <更快
===================================
更新 - 下一次测试(另一轮)
===================================
------
测试替换字符串速度。
测试一:26535.6466
测试二:26379.6464
测试三:26379.6463
平均值:26431.6464333333
速度:100%
------
测试 Foreach 字符字符串追加。
测试一:8502.015
测试二:8517.6149
测试三:8595.6151
平均:8538.415
速度:309.56%
------
测试 Foreach 字符字符串追加(修复 StringBuilder 长度)。
测试一:8314.8146
测试二:8330.4147
测试三:8346.0146
平均值:8330.41463333333
速度:317.29%


结论:
使用 Foreach Char Loop 和 Append 比 String.Replace() 更快。

非常感谢你们。

------
以下是我用来运行测试的代码:(已编辑)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Write("Press any key to continue...");
            Console.ReadKey();
            Console.Write("\r\nProcess started.");
            Test();
            Console.WriteLine("Done.");
            Console.Read();
        }

        public static Random random = new Random((int)DateTime.Now.Ticks);

        public static string RandomString(int size)
        {
            StringBuilder sb = new StringBuilder();
            char ch;
            for (int i = 0; i < size; i++)
            {
                ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
                sb.Append(ch);
            }
            return sb.ToString();
        }

        public static void Test()
        {
            string text = "\\_\r\n\a\b\f\t\v\"'" + RandomString(2000) + "\\_\r\n\a\b\f\t\v\"'" + RandomString(2000);

            List<TimeSpan> lstTimeUsed = new List<TimeSpan>();

            int target = 100000;

            for (int i = 0; i < 3; i++)
            {
                DateTime startTime = DateTime.Now;
                for (int j = 0; j < target; j++)
                {
                    if (j.ToString().EndsWith("000"))
                    {
                        Console.Clear();
                        Console.WriteLine("Test " + i.ToString());
                        Console.WriteLine(j.ToString() + " of " + target.ToString());
                    }

                    string data = text;

                    data = data.Replace("\\", "\\\\"); // Backslash
                    data = data.Replace("\r", "\\r");  // Carriage return
                    data = data.Replace("\n", "\\n");  // New Line
                    data = data.Replace("\a", "\\a");  // Vertical tab
                    data = data.Replace("\b", "\\b");  // Backspace
                    data = data.Replace("\f", "\\f");  // Formfeed
                    data = data.Replace("\t", "\\t");  // Horizontal tab
                    data = data.Replace("\v", "\\v");  // Vertical tab
                    data = data.Replace("\"", "\\\""); // Double quotation mark
                    data = data.Replace("'", "\\'");   // Single quotation mark

                }
                DateTime endTime = DateTime.Now;
                TimeSpan ts = endTime - startTime;
                lstTimeUsed.Add(ts);
            }

            double t1 = lstTimeUsed[0].TotalMilliseconds;
            double t2 = lstTimeUsed[1].TotalMilliseconds;
            double t3 = lstTimeUsed[2].TotalMilliseconds;
            double tOri = (t1 + t2 + t3) / 3;

            System.IO.TextWriter tw = new System.IO.StreamWriter("D:\\test.txt", true);
            tw.WriteLine("------");
            tw.WriteLine("Test Replace String Speed. Test Time: " + DateTime.Now.ToString());
            tw.WriteLine("Test 1: " + t1.ToString());
            tw.WriteLine("Test 2: " + t2.ToString());
            tw.WriteLine("Test 3: " + t3.ToString());
            tw.WriteLine("Average: " + tOri.ToString());
            tw.WriteLine("Speed: 100%");
            tw.Close();

            lstTimeUsed = new List<TimeSpan>();

            for (int i = 0; i < 3; i++)
            {
                DateTime startTime = DateTime.Now;
                for (int j = 0; j < target; j++)
                {
                    if (j.ToString().EndsWith("000"))
                    {
                        Console.Clear();
                        Console.WriteLine("Test " + i.ToString());
                        Console.WriteLine(j.ToString() + " of " + target.ToString());
                    }

                    string data = text;

                    var builder = new StringBuilder();
                    foreach (var ch in data)
                    {
                        switch (ch)
                        {
                            case '\\':
                            case '\r':
                            case '\n':
                            case '\a':
                            case '\b':
                            case '\f':
                            case '\t':
                            case '\v':
                            case '\"':
                            case '\'':
                                builder.Append('\\');
                                break;
                            default:
                                break;
                        }
                        builder.Append(ch);
                    }

                }
                DateTime endTime = DateTime.Now;
                TimeSpan ts = endTime - startTime;
                lstTimeUsed.Add(ts);
            }

            t1 = lstTimeUsed[0].TotalMilliseconds;
            t2 = lstTimeUsed[1].TotalMilliseconds;
            t3 = lstTimeUsed[2].TotalMilliseconds;

            tw = new System.IO.StreamWriter("D:\\test.txt", true);
            tw.WriteLine("------");
            tw.WriteLine("Test Foreach Char String Append. Test Time: " + DateTime.Now.ToString());
            tw.WriteLine("Test 1: " + t1.ToString());
            tw.WriteLine("Test 2: " + t2.ToString());
            tw.WriteLine("Test 3: " + t3.ToString());
            tw.WriteLine("Average: " + ((t1 + t2 + t3) / 3).ToString());
            tw.WriteLine("Speed: " + ((tOri) / ((t1 + t2 + t3) / 3) * 100).ToString("0.00") + "%");
            tw.Close();

            lstTimeUsed = new List<TimeSpan>();

            for (int i = 0; i < 3; i++)
            {
                DateTime startTime = DateTime.Now;
                for (int j = 0; j < target; j++)
                {
                    if (j.ToString().EndsWith("000"))
                    {
                        Console.Clear();
                        Console.WriteLine("Test " + i.ToString());
                        Console.WriteLine(j.ToString() + " of " + target.ToString());
                    }

                    string data = text;

                    var builder = new StringBuilder(data.Length + 20);
                    foreach (var ch in data)
                    {
                        switch (ch)
                        {
                            case '\\':
                            case '\r':
                            case '\n':
                            case '\a':
                            case '\b':
                            case '\f':
                            case '\t':
                            case '\v':
                            case '\"':
                            case '\'':
                                builder.Append('\\');
                                break;
                            default:
                                break;
                        }
                        builder.Append(ch);
                    }

                }
                DateTime endTime = DateTime.Now;
                TimeSpan ts = endTime - startTime;
                lstTimeUsed.Add(ts);
            }

            t1 = lstTimeUsed[0].TotalMilliseconds;
            t2 = lstTimeUsed[1].TotalMilliseconds;
            t3 = lstTimeUsed[2].TotalMilliseconds;

            tw = new System.IO.StreamWriter("D:\\test.txt", true);
            tw.WriteLine("------");
            tw.WriteLine("Test Foreach Char String Append (Fix StringBuilder Length). Test Time: " + DateTime.Now.ToString());
            tw.WriteLine("Test 1: " + t1.ToString());
            tw.WriteLine("Test 2: " + t2.ToString());
            tw.WriteLine("Test 3: " + t3.ToString());
            tw.WriteLine("Average: " + ((t1 + t2 + t3) / 3).ToString());
            tw.WriteLine("Speed: " + ((tOri) / ((t1 + t2 + t3) / 3) * 100).ToString("0.00") + "%");
            tw.Close();

        }
    }
}

最佳答案

    var builder = new StringBuilder(data.Length + 20);
    foreach (var ch in data)
    {
      switch (ch)
      {
        case '\\':
        case '\r':
        ...
          builder.Append('\\');
          break;
      }
      builder.Append(ch);
    }
    return builder.ToString();

关于c# - 比 String.Replace() 更快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11236976/

相关文章:

c# - EF 编译查询偶尔导致 SqlException

html - 显示 : None + Load Time

c# - .NET 应用程序在长时间不活动后速度非常慢

python - 将 numpy 数组中的连续值及其长度分组

java - 切换到 Java 7 时构建时间显着增加

c# - 对于大型 JSON 请求,Web API POST 参数为空

c# - excel中的第一个空行

database - 嵌入式沙发数据库

c# - SignalR 我可以传递数据集吗

c# - Excel.Worksheet.Cells 具有相反的行为?