我有一个字符串,需要将其中的标记替换为字典中的值.它必须尽可能高效.使用字符串.place执行循环只会消耗内存(记住,字符串是不可变的).StringBuilder.Replace()会不会更好,因为它是为处理字符串操作而设计的?

我希望避免RegEx的费用,但如果这将是一个更有效率的,那么就这样吧.

注意:我不关心代码的复杂性,只关心它的运行速度和占用的内存.

平均统计数据:Length255-1024个字符,字典中有15-30个键.

推荐答案

使用RedGate Profiler使用以下代码

class Program
    {
        static string data = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz";
        static Dictionary<string, string> values;

        static void Main(string[] args)
        {
            Console.WriteLine("Data length: " + data.Length);
            values = new Dictionary<string, string>()
            {
                { "ab", "aa" },
                { "jk", "jj" },
                { "lm", "ll" },
                { "yz", "zz" },
                { "ef", "ff" },
                { "st", "uu" },
                { "op", "pp" },
                { "x", "y" }
            };

            StringReplace(data);
            StringBuilderReplace1(data);
            StringBuilderReplace2(new StringBuilder(data, data.Length * 2));

            Console.ReadKey();
        }

        private static void StringReplace(string data)
        {
            foreach(string k in values.Keys)
            {
                data = data.Replace(k, values[k]);
            }
        }

        private static void StringBuilderReplace1(string data)
        {
            StringBuilder sb = new StringBuilder(data, data.Length * 2);
            foreach (string k in values.Keys)
            {
                sb.Replace(k, values[k]);
            }
        }

        private static void StringBuilderReplace2(StringBuilder data)
        {
            foreach (string k in values.Keys)
            {
                data.Replace(k, values[k]);
            }
        }
    }
  • 一串更换=5.843ms
  • StringBuilder.更换#1=4.059ms
  • Stringbuilder.替换#2=0.461ms

字符串长度=1456

字符串生成器#1在方法中创建字符串生成器,而#2不创建,因此性能差异很可能最终是相同的,因为您只是将工作移出方法.如果您从字符串生成器开始,而不是字符串,那么#2可能是替代的方法.

就内存而言,在使用RedGateMemory分析器之前,没有什么可担心的,直到您进行了许多替换操作,在这些操作中,Stringbuilder总体上是赢家.

.net相关问答推荐

.NET Blazor-使用子组件中的处理程序方法进行双向数据绑定

ASP.NET核心最小API必须以正斜杠开头吗?

如何在dotnet中使用OpenTelemetry Prometheus导出器导出多个版本的度量?

在 Inno Setup 中判断给定服务的依赖服务

从 Contentful 中的富文本元素中获取价值?

Ubuntu 22.04 + JetBrains Rider 不能做脚手架 dbContext

在 C# 中,如何使用泛型的基类将泛型接口的所有实例注入到单个构造函数中?

xunit Assert.ThrowsAsync() 不能正常工作?

.NET 的future 版本会支持 C# 中的元组吗?

将 DataRowCollection 转换为 IEnumerable

是否可以模拟 .NET HttpWebResponse?

如何以编程方式 Select ListView 中的项目?

Await 运算符只能在 Async 方法中使用

.NET 的 String.Normalize 有什么作用?

监听依赖属性的变化

如何在多个解决方案之间共享相同的 Resharper 设置,无需人工干预?

文件按文件名模式存在

哪个密码字符在 winforms 文本框中显示黑点 (•)?

string.Empty vs null.你用哪一个?

可以从 C# 调用 C++ 代码吗?