Kry*_*hic 92 c# string resharper performance string-interpolation
使用字符串插值之间是否存在显着的性能差异:
myString += $"{x:x2}";
Run Code Online (Sandbox Code Playgroud)
vs String.Format()?
myString += String.Format("{0:x2}", x);
Run Code Online (Sandbox Code Playgroud)
我只是问,因为Resharper正在提示修复,我之前被愚弄了.
l33*_*33t 21
答案是肯定的和否定的。通过不显示第三个变体ReSharper 来愚弄您,这也是性能最高的。列出的两个变体产生相同的 IL 代码,但以下确实会带来提升:
myString += $"{x.ToString("x2")}";
Run Code Online (Sandbox Code Playgroud)
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
using BenchmarkDotNet.Diagnosers;
using BenchmarkDotNet.Diagnostics.Windows;
using BenchmarkDotNet.Running;
namespace StringFormatPerformanceTest
{
[Config(typeof(Config))]
public class StringTests
{
private class Config : ManualConfig
{
public Config() => AddDiagnoser(MemoryDiagnoser.Default, new EtwProfiler());
}
[Params(42, 1337)]
public int Data;
[Benchmark] public string Format() => string.Format("{0:x2}", Data);
[Benchmark] public string Interpolate() => $"{Data:x2}";
[Benchmark] public string InterpolateExplicit() => $"{Data.ToString("x2")}";
}
class Program
{
static void Main(string[] args)
{
var summary = BenchmarkRunner.Run<StringTests>();
}
}
}
Run Code Online (Sandbox Code Playgroud)
| Method | Data | Mean | Gen 0 | Allocated |
|-------------------- |----- |----------:|-------:|----------:|
| Format | 42 | 118.03 ns | 0.0178 | 56 B |
| Interpolate | 42 | 118.36 ns | 0.0178 | 56 B |
| InterpolateExplicit | 42 | 37.01 ns | 0.0102 | 32 B |
| Format | 1337 | 117.46 ns | 0.0176 | 56 B |
| Interpolate | 1337 | 113.86 ns | 0.0178 | 56 B |
| InterpolateExplicit | 1337 | 38.73 ns | 0.0102 | 32 B |
Run Code Online (Sandbox Code Playgroud)
该InterpolateExplicit()方法更快,因为我们现在明确告诉编译器使用string. 无需对要格式化的对象进行装箱。拳击确实是非常昂贵的。另外,请注意我们稍微减少了分配。
Dav*_*ack 16
您应该注意到,C#10 和 .NET 6 中的字符串插值进行了重大优化 - C# 10 和 .NET 6 中的字符串插值。
我不仅迁移了字符串格式化的所有用法,还迁移了字符串连接的用法,以使用字符串插值。
我同样担心(如果不是更多的话)不同方法之间的内存分配差异。我发现,当处理少量字符串时,字符串插值几乎总是在速度和内存分配方面获胜。如果您有未确定的(在设计时未知)数量的字符串,则应始终使用System.Text.StringBuilder.Append(xxx)或System.Text.StringBuilder.AppendFormat(xxx)
另外,我会指出您+=对字符串连接的用法。要非常小心,并且只对少量的小字符串执行此操作。
小智 5
字符串插值在编译时转换为string.Format()。
同样在string.Format中,您可以为单个参数指定多个输出,并为单个参数指定不同的输出格式。但是我猜想字符串插值更易读。因此,取决于您。
a = string.Format("Due date is {0:M/d/yy} at {0:h:mm}", someComplexObject.someObject.someProperty);
b = $"Due date is {someComplexObject.someObject.someProperty:M/d/yy} at {someComplexObject.someObject.someProperty:h:mm}";
Run Code Online (Sandbox Code Playgroud)
问题是关于性能的,但是标题只是说“vs”,所以我觉得必须补充一些观点,尽管其中一些观点是固执己见的。
本土化
string.Format. 然而,有一些工具可以做到这一点(例如ReSharper)。可维护性(我的意见)
string.Format更具可读性,因为它专注于我想要表达的句子,例如在构建漂亮且有意义的错误消息时。使用{N}占位符给了我更大的灵活性,并且以后更容易修改它。string.Format不太容易出现这种情况。因此,基于这些,我决定坚持使用string.Format我的大部分代码。不过,我准备了一个扩展方法,以获得我更喜欢的更流畅的编码方式。该扩展的实现是单行的,在使用中看起来就像这样。
var myErrorMessage = "Value must be less than {0:0.00} for field {1}".FormatWith(maximum, fieldName);
Run Code Online (Sandbox Code Playgroud)
插值是一个很棒的功能,请不要误会我的意思。但在我看来,它在那些缺少类似功能的语言中表现得最好string.Format,例如 JavaScript。
| 归档时间: |
|
| 查看次数: |
25604 次 |
| 最近记录: |