文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

.NET8极致性能优化Primitives-DateTime

2024-11-30 04:14

关注

概述

DateTime 和 DateTimeOffset 为例。dotnet/runtime#84963 改进了 DateTime{Offset} 格式化的各种方面:

以下示例展现出一些影响:

// dotnet run -c Release -f net7.0 --filter "*" --runtimes net7.0 net8.0


using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System.Globalization;


BenchmarkSwitcher.FromAssembly(typeof(Tests).Assembly).Run(args);


[HideColumns("Error", "StdDev", "Median", "RatioSD")]
[MemoryDiagnoser(displayGenColumns: false)]
public class Tests
{
    private readonly DateTime _dt = new DateTime(2023, 9, 1, 12, 34, 56);
    private readonly char[] _chars = new char[100];


    [Params(null, "s", "u", "U", "G")]
    public string Format { get; set; }


    [Benchmark] public string DT_ToString() => _dt.ToString(Format);
    [Benchmark] public string DT_ToStringInvariant() => _dt.ToString(Format, CultureInfo.InvariantCulture);
    [Benchmark] public bool DT_TryFormat() => _dt.TryFormat(_chars, out _, Format);
    [Benchmark] public bool DT_TryFormatInvariant() => _dt.TryFormat(_chars, out _, Format, CultureInfo.InvariantCulture);
}

性能测试如下:

Method

Runtime

Format

Mean

Ratio

Allocated

Alloc Ratio

DT_ToString

.NET 7.0

?

166.64 ns

00

64 B

00

DT_ToString

.NET 8.0

?

102.45 ns

0.62

64 B

00








DT_ToStringInvariant

.NET 7.0

?

161.94 ns

00

64 B

00

DT_ToStringInvariant

.NET 8.0

?

74 ns

0.18

64 B

00








DT_TryFormat

.NET 7.0

?

151.52 ns

00

NA

DT_TryFormat

.NET 8.0

?

57 ns

0.52

NA








DT_TryFormatInvariant

.NET 7.0

?

140.35 ns

00

NA

DT_TryFormatInvariant

.NET 8.0

?

26 ns

0.13

NA








DT_ToString

.NET 7.0

G

162.86 ns

00

64 B

00

DT_ToString

.NET 8.0

G

109.49 ns

0.68

64 B

00








DT_ToStringInvariant

.NET 7.0

G

162.20 ns

00

64 B

00

DT_ToStringInvariant

.NET 8.0

G

102.71 ns

0.63

64 B

00








DT_TryFormat

.NET 7.0

G

148.32 ns

00

NA

DT_TryFormat

.NET 8.0

G

60 ns

0.57

NA








DT_TryFormatInvariant

.NET 7.0

G

145.05 ns

00

NA

DT_TryFormatInvariant

.NET 8.0

G

77 ns

0.55

NA








DT_ToString

.NET 7.0

s

186.44 ns

00

64 B

00

DT_ToString

.NET 8.0

s

35 ns

0.17

64 B

00








DT_ToStringInvariant

.NET 7.0

s

182.15 ns

00

64 B

00

DT_ToStringInvariant

.NET 8.0

s

67 ns

0.16

64 B

00








DT_TryFormat

.NET 7.0

s

165.08 ns

00

NA

DT_TryFormat

.NET 8.0

s

53 ns

0.09

NA








DT_TryFormatInvariant

.NET 7.0

s

155.24 ns

00

NA

DT_TryFormatInvariant

.NET 8.0

s

50 ns

0.10

NA








DT_ToString

.NET 7.0

u

184.71 ns

00

64 B

00

DT_ToString

.NET 8.0

u

62 ns

0.16

64 B

00








DT_ToStringInvariant

.NET 7.0

u

184.01 ns

00

64 B

00

DT_ToStringInvariant

.NET 8.0

u

98 ns

0.15

64 B

00








DT_TryFormat

.NET 7.0

u

171.73 ns

00

NA

DT_TryFormat

.NET 8.0

u

08 ns

0.09

NA








DT_TryFormatInvariant

.NET 7.0

u

158.42 ns

00

NA

DT_TryFormatInvariant

.NET 8.0

u

58 ns

0.10

NA








DT_ToString

.NET 7.0

U

1,622.28 ns

00

1240 B

00

DT_ToString

.NET 8.0

U

206.08 ns

0.13

96 B

0.08








DT_ToStringInvariant

.NET 7.0

U

1,567.92 ns

00

1240 B

00

DT_ToStringInvariant

.NET 8.0

U

207.60 ns

0.13

96 B

0.08








DT_TryFormat

.NET 7.0

U

1,590.27 ns

00

1144 B

00

DT_TryFormat

.NET 8.0

U

190.98 ns

0.12

0.00








DT_TryFormatInvariant

.NET 7.0

U

1,560.00 ns

00

1144 B

00

DT_TryFormatInvariant

.NET 8.0

U

184.11 ns

0.12

0.00

解析也有了有意义的改进。例如改进了自定义格式字符串中“ddd”(一周中某天的缩写名称)、“dddd”(一周中某天的全名)、“MMM”(月份的缩写名称)和“MMMM”(月份的全名)的处理;这些在各种常用格式字符串中都有出现,比如在 RFC1123 格式的扩展定义中:ddd, dd MMM yyyy HH':'mm':'ss 'GMT'。当通用解析例程在格式字符串中遇到这些时,它需要查阅提供的 CultureInfo / DateTimeFormatInfo,以获取该语言区域设置的相关月份和日期名称,例如 DateTimeFormatInfo.GetAbbreviatedMonthName,然后需要对每个名称和输入文本进行语言忽略大小写的比较;开销很大。然而,如果我们得到的是一个不变的语言区域设置,我们可以做得更快,快得多。以“MMM”为例,代表缩写的月份名称。我们可以读取接下来的三个字符(uint m0 = span[0], m1 = span[1], m2 = span[2]),确保它们都是 ASCII ((m0 | m1 | m2) <= 0x7F),然后将它们全部合并成一个单独的 uint,使用之前讨论过的相同的 ASCII 大小写技巧 ((m0 << 16) | (m1 << 8) | m2 | 0x202020)。我们可以对每个月份名称做同样的事情,这些对于不变的语言区域设置我们提前知道,整个查找变成了一个单一的数字切换:

switch ((m0 << 16) | (m1 << 8) | m2 | 0x202020)
{
    case 0x6a616e:  result = 1; break;
    case 0x666562:  result = 2; break;
    case 0x6d6172:  result = 3; break;
    case 0x617072:  result = 4; break;
    case 0x6d6179:  result = 5; break;
    case 0x6a756e:  result = 6; break;
    case 0x6a756c:  result = 7; break;
    case 0x617567:  result = 8; break;
    case 0x736570:  result = 9; break;
    case 0x6f6374:  result = 10; break;
    case 0x6e6f76:  result = 11; break;
    case 0x646563:  result = 12; break;
    default: maxMatchStrLen = 0; break; // undo match assumption
}

优雅,而且速度更快。

// dotnet run -c Release -f net7.0 --filter "*" --runtimes net7.0 net8.0


using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using System.Globalization;


BenchmarkSwitcher.FromAssembly(typeof(Tests).Assembly).Run(args);


[HideColumns("Error", "StdDev", "Median", "RatioSD")]
[MemoryDiagnoser(displayGenColumns: false)]
public class Tests
{
    private const string Format = "ddd, dd MMM yyyy HH':'mm':'ss 'GMT'";


    private readonly string _s = new DateTime(1955, 11, 5, 6, 0, 0, DateTimeKind.Utc).ToString(Format, CultureInfo.InvariantCulture);


    [Benchmark]
    public void ParseExact() => DateTimeOffset.ParseExact(_s, Format, CultureInfo.InvariantCulture, DateTimeStyles.AllowInnerWhite | DateTimeStyles.AssumeUniversal);
}

性能对比:

方法

运行时

平均值

比率

分配

分配比率

ParseExact

.NET 7.0

1,139.3 ns

00

80 B

00

ParseExact

.NET 8.0

318.6 ns

0.28

0.00


来源:江湖评谈内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯