C#日期解构和格式化对比

前言

在技术群看到使用日期解构的用法,便试试通过解构的方式和格式化日期进行对比,刚开始还以为格式化日期的方式性能更好一些(经验主义害死人),在进行简单的性能基准测试后,日期解构的方式性能更好一些.

代码

//1. 使用解构的方式,分别获取年月日和时分秒
var ((year, month, day), (hour, minute, second)) = DateTime.Now;
var datetimeStr = $"{year}-{month}-{day} {hour}:{minute}:{second}";
Console.WriteLine(datetimeStr);

//2. 使用ToString的方式获取日期时间的字符串
var datetimeStr1 = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
Console.WriteLine(datetimeStr1);

看一下运行结果:

通过日期解构的方式,提取年月日和时分秒,生成日期的的字符串

学习一下日期的解构

// 通过日期的解构函数,分别获取到 日期(DateOnly)和时间(TimeOnly)
var ((year, month, day), (hour, minute, second)) = DateTime.Now;

//通过反编译的方式,得到以下代码
DateOnly dateOnly;
TimeOnly timeOnly;
DateTime.Now.Deconstruct(out dateOnly, out timeOnly); //第一次DateTime解构获取DateOnly和TimeOnly
DateOnly dateOnly2 = dateOnly;
int num;
int num2;
int num3;
dateOnly2.Deconstruct(out num, out num2, out num3);  //第二次通过DateOnly的解构获取年月日
TimeOnly timeOnly2 = timeOnly;
int num4;
int num5;
int num6;
timeOnly2.Deconstruct(out num4, out num5, out num6); //第三次通过TimeOnly的解构获取时分秒
int year = num;
int month = num2;
int day = num3;
int hour = num4;
int minute = num5;
int second = num6;

//字符串插值,生成格式化的日期字符串,减少拼接字符,产生的临时字符串
DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(5, 6);
defaultInterpolatedStringHandler.AppendFormatted<int>(year);
defaultInterpolatedStringHandler.AppendLiteral("-");
defaultInterpolatedStringHandler.AppendFormatted<int>(month);
defaultInterpolatedStringHandler.AppendLiteral("-");
defaultInterpolatedStringHandler.AppendFormatted<int>(day);
defaultInterpolatedStringHandler.AppendLiteral(" ");
defaultInterpolatedStringHandler.AppendFormatted<int>(hour);
defaultInterpolatedStringHandler.AppendLiteral(":");
defaultInterpolatedStringHandler.AppendFormatted<int>(minute);
defaultInterpolatedStringHandler.AppendLiteral(":");
defaultInterpolatedStringHandler.AppendFormatted<int>(second);
string datetimeStr = defaultInterpolatedStringHandler.ToStringAndClear();

性能基准测试

using System;
using BenchmarkDotNet.Attributes;

namespace CSharpBenchmarks.StringTest;

[DisassemblyDiagnoser(printSource: true, maxDepth: 3)]
[MemoryDiagnoser]
public class DatetimeStringTest
{
	[Params(128, 1024)]
	public int Count { get; set; }


	[Benchmark(Baseline = true)]
	public void Deconstruct()
	{
		var sum = 0;
		for (var i = 0; i < Count; i++)
		{
			var ((year, month, day), (hour, minute, second)) = DateTime.Now; //解构
			var s = $"{year}-{month}-{day} {hour}:{minute}:{second}";
			sum += s.Length;
		}
	}

	[Benchmark]
	public void String()
	{
		var sum = 0;
		for (var i = 0; i < Count; i++)
		{
			var s = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");  //格式化,本质上是调用DateTimeFormat.Format处理
			sum += s.Length;
		}
	}
}

看一下测试结果:

对比日期解构和格式化性能

通过性能基准测试,可以看到日期解构和日期格式化,解构的性能比格式化性能要快29%和35%之间,在执行1024次后,内存也比格式化少了14%,和0代GC也少了2次回收.其实如果认真思考后,也就明白了为什么日期格式化会慢了,因为这里的日期解构是没考虑区域和通用,正常使用还是使用日期格式化的方式.

秋风 2026-04-12