为DateTime使用变量有多重要?今天当关心业绩

本文关键字:今天 关心 DateTime 变量 | 更新日期: 2023-09-27 18:07:25

我刚刚看到这个被点赞的评论

IIRC DateTime.Today是一个非常昂贵的调用,所以您最好先将值存储在一个变量中。

这是对一个包含代码的帖子的回应:

var first = 
    new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1).AddMonths(-1);
var last = 
    new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1).AddDays(-1);

如果我想提高性能,将DateTime.Today存储在变量中而不是多次调用它有多重要?DateTime.Today的多少次使用将证明为它创建一个变量是合理的?

编辑:我意识到我应该先测试我的程序,看看是否有性能问题,然后再担心像这样琐碎的事情。为了解决这个问题,假设我已经完成了这些工作,并确定需要进行额外的优化。

为DateTime使用变量有多重要?今天当关心业绩

保存DateTime有多重要。今天在一个变量

最好的答案是在您期望代码运行的硬件上进行基准测试。除非你在一个非常紧密的循环中调用它,否则我怀疑这将是一个问题。

将其存储在变量中的一个更好的理由是,您可能会在两次调用之间从一天切换到另一天。

为了提供一个数量级,@RichardBrown在他的回答中分享了一个链接,表明DateTime.Today的成本被测试为几百纳秒的数量级(在用于该测试的特定硬件上)。

基准测试(在我的机器上,使用Stopwatch类):

10,000 DateTime.Today calls and assignment to local variable: 0.0125781 seconds.
10,000 Assignment only operations: 0.0001062 seconds.
代码:

var s = new Stopwatch();
DateTime date = DateTime.Today;
DateTime date2 = DateTime.Today;
s.Start();
for (int i=0; i<10000; i++)
    date = DateTime.Today;
s.Stop();
Debug.Print(s.Elapsed.ToString());
s.Reset();
s.Start();
for (int i=0; i<10000; i++)
    date2 = date;
s.Stop();
Debug.Print(s.Elapsed.ToString());

我拒绝DateTime.Today是一个昂贵调用的前提。如果重要的是它不能随时间变化,那么应该将它存储在一个变量中。如果这段代码在月末的午夜左右运行,你可能会遇到……问题。从性能的角度来看,我非常怀疑这会是个问题。

在任何情况下,这都是一个微优化。对于任何性能问题,如果您的工作程序太慢,您应该对其进行分析,寻找花费大量时间的部分,并专注于优化这些部分,寻找花费比您预期更多时间运行的代码。如果这一行代码耗费了大量时间,那么考虑修改它。在此之前,只重构它的正确性和可读性,而不是性能。

关于DateTime性能的确切数字请阅读这篇博文。正如前面的回答所述,在确定性能时,查看您的特定配置和需求非常重要。

如果你在循环中调用代码,我猜这是一个问题。但最好的方法是计算时间,看看自己花了多长时间。

var sw = new Stopwatch();
sw.Start();
today = DateTime.Today();
sw.Stop();
var ts = stopWatch.Elapsed;

MSDN秒表参考

DateTime.Today提取为变量的真正原因是为了防止由于墨菲定律出现但永远无法被隔离和修复的可能的bug .

想法是在第一次和第二次使用Today的实际日期之间可能会更改,因此您可以在这里获得,例如,上一年和新月份:
var first = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1).AddMonths(-1);

可能导致(January 2013) - 1 month而不是(December 2013) - 1 month

如果firstlast之间的日期发生了变化,则更有可能出现更糟糕的问题:

var first = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1).AddMonths(-1);
var last = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1).AddDays(-1);

这将导致一年多的周期…根据您的逻辑,这可能会导致非常昂贵的损失。

比性能问题更重要的是代码的可读性和可维护性。

除非你没有性能问题,否则我会遵循"关注性能改进"的规则

也许如果你有一个循环,那么一个变量可以用"today"来命名,但是只要没有性能问题,我就会关注其他问题