- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
首先:
我问这个问题只是为了好玩和渴望学习。我不得不承认我喜欢搞乱微优化(尽管它们从未导致我的任何开发速度显着提高)。
DateTime.DayOfWeek
方法并不代表我的任何应用程序中的瓶颈。
而且它极不可能成为任何其他方面的问题。如果有人认为此方法对其应用程序的性能有影响,他应该考虑When to optimize然后,他应该进行分析。
用ILSpy反编译DateTime
类,我们发现DateTime.DayOfWeek
是如何实现的:
public DayOfWeek DayOfWeek
{
[__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
get
{
return (DayOfWeek)((this.InternalTicks / 864000000000L + 1L) % 7L);
}
}
public long Ticks
{
[__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
get
{
return this.InternalTicks;
}
}
此方法执行以下操作:
当天对应的分时数除以一天中现有的分时数。
我们对上述结果加1,使7除的余数在0和6之间。
这是计算星期几的唯一方法吗?
是否可以重新实现它以使其运行得更快?
最佳答案
让我们做一些调整。
TimeSpan.TicksPerDay
(864000000000)
的质因数分解: DayOfWeek
现在可以表示为:
public DayOfWeek DayOfWeek
{
get
{
return (DayOfWeek)(((Ticks>>14) / 52734375 + 1L) % 7L);
}
}
我们对 7 求模,52734375 % 7
是 1。所以,上面的代码等于:
public static DayOfWeek dayOfWeekTurbo(this DateTime date)
{
return (DayOfWeek)(((date.Ticks >> 14) + 1) % 7);
}
直觉上,它是有效的。但让我们用代码
证明一下public static void proof()
{
DateTime date = DateTime.MinValue;
DateTime max_date = DateTime.MaxValue.AddDays(-1);
while (date < max_date)
{
if (date.DayOfWeek != date.dayOfWeekTurbo())
{
Console.WriteLine("{0}\t{1}", date.DayOfWeek, date.dayOfWeekTurbo());
Console.ReadLine();
}
date = date.AddDays(1);
}
}
如果你愿意,你可以运行它,但我向你保证它工作正常。
好的,唯一剩下的就是一些基准测试。
这是一个辅助方法,为了让代码更清晰:
public static IEnumerable<DateTime> getAllDates()
{
DateTime d = DateTime.MinValue;
DateTime max = DateTime.MaxValue.AddDays(-1);
while (d < max)
{
yield return d;
d = d.AddDays(1);
}
}
我想这不需要解释。
public static void benchDayOfWeek()
{
DateTime[] dates = getAllDates().ToArray();
// for preventing the compiler doing things that we don't want to
DayOfWeek[] foo = new DayOfWeek[dates.Length];
for (int max_loop = 0; max_loop < 10000; max_loop+=100)
{
Stopwatch st1, st2;
st1 = Stopwatch.StartNew();
for (int i = 0; i < max_loop; i++)
for (int j = 0; j < dates.Length; j++)
foo[j] = dates[j].DayOfWeek;
st1.Stop();
st2 = Stopwatch.StartNew();
for (int i = 0; i < max_loop; i++)
for (int j = 0; j < dates.Length; j++)
foo[j] = dates[j].dayOfWeekTurbo();
st2.Stop();
Console.WriteLine("{0},{1}", st1.ElapsedTicks, st2.ElapsedTicks);
}
Console.ReadLine();
Console.WriteLine(foo[0]);
}
输出:
96,28
172923452,50884515
352004290,111919170
521851120,168153321
683972846,215554958
846791857,264187194
1042803747,328459950
Monday
如果我们用数据制作图表,它看起来像这样:
╔══════════════════════╦════════════════════╦═════════════════════╦═════════════╗
║ Number of iterations ║ Standard DayOfWeek ║ Optimized DayOfWeek ║ Speedup ║
╠══════════════════════╬════════════════════╬═════════════════════╬═════════════╣
║ 0 ║ 96 ║ 28 ║ 3.428571429 ║
║ 100 ║ 172923452 ║ 50884515 ║ 3.398351188 ║
║ 200 ║ 352004290 ║ 111919170 ║ 3.145165301 ║
║ 300 ║ 521851120 ║ 168153321 ║ 3.103424404 ║
║ 400 ║ 683972846 ║ 215554958 ║ 3.1730787 ║
║ 500 ║ 846791857 ║ 264187194 ║ 3.205272156 ║
║ 600 ║ 1042803747 ║ 328459950 ║ 3.174827698 ║
╚══════════════════════╩════════════════════╩═════════════════════╩═════════════╝
快 3 倍。
注意:代码是使用 Visual Studio 2013 Release模式编译的,并在除应用程序之外的所有内容都关闭的情况下运行。 (当然包括VS)。
我在 a toshiba Satellite C660-2JK 中运行了测试,英特尔® 酷睿™ i3-2350M 处理器和 Windows® 7 家庭高级版 64 位。
编辑:
正如 Jon Skeet 所注意到的,此方法在不在日期边界上时可能会失败。
由于 Jon Skeet 对这个答案的评论,
dayOfWeekTurbo
can fail when it's not on a date boundary. For example, considernew DateTime(2014, 3, 11, 21, 39, 30)
- your method thinks it's Friday when actually it's Tuesday. The "we are working in modulo 7" is the wrong way round, basically... by removing that extra division, the day-of-week changes during the day.
我决定编辑它。
如果我们改变proof()
方法,
public static void proof()
{
DateTime date = DateTime.MinValue;
DateTime max_date = DateTime.MaxValue.AddSeconds(-1);
while (date < max_date)
{
if (date.DayOfWeek != date.dayOfWeekTurbo2())
{
Console.WriteLine("{0}\t{1}", date.DayOfWeek, date.dayOfWeekTurbo2());
Console.ReadLine();
}
date = date.AddSeconds(1);
}
}
失败!
Jon Skeet 是对的。让我们听从 Jon Skeet 的建议并应用除法。
public static DayOfWeek dayOfWeekTurbo2(this DateTime date)
{
return (DayOfWeek)((((date.Ticks >> 14) / 52734375L )+ 1) % 7);
}
此外,我们更改方法 getAllDates()
。
public static IEnumerable<DateTime> getAllDates()
{
DateTime d = DateTime.MinValue;
DateTime max = DateTime.MaxValue.AddHours(-1);
while (d < max)
{
yield return d;
d = d.AddHours(1);
}
}
和benchDayOfWeek()
public static void benchDayOfWeek()
{
DateTime[] dates = getAllDates().ToArray();
DayOfWeek[] foo = new DayOfWeek[dates.Length];
for (int max_loop = 0; max_loop < 10000; max_loop ++)
{
Stopwatch st1, st2;
st1 = Stopwatch.StartNew();
for (int i = 0; i < max_loop; i++)
for (int j = 0; j < dates.Length; j++)
foo[j] = dates[j].DayOfWeek;
st1.Stop();
st2 = Stopwatch.StartNew();
for (int i = 0; i < max_loop; i++)
for (int j = 0; j < dates.Length; j++)
foo[j] = dates[j].dayOfWeekTurbo2();
st2.Stop();
Console.WriteLine("{0},{1}", st1.ElapsedTicks, st2.ElapsedTicks);
}
Console.ReadLine();
Console.WriteLine(foo[0]);
}
还会更快吗?答案是是
输出:
90,26
43772675,17902739
84299562,37339935
119418847,47236771
166955278,72444714
207441663,89852249
223981096,106062643
275440586,125110111
327353547,145689642
363908633,163442675
407152133,181642026
445141584,197571786
495590201,217373350
520907684,236609850
511052601,217571474
610024381,260208969
637676317,275558318
╔══════════════════════╦════════════════════╦════════════════════════╦═════════════╗
║ Number of iterations ║ Standard DayOfWeek ║ Optimized DayOfWeek(2) ║ Speedup ║
╠══════════════════════╬════════════════════╬════════════════════════╬═════════════╣
║ 1 ║ 43772675 ║ 17902739 ║ 2.445026708 ║
║ 2 ║ 84299562 ║ 37339935 ║ 2.257624766 ║
║ 3 ║ 119418847 ║ 47236771 ║ 2.528090817 ║
║ 4 ║ 166955278 ║ 72444714 ║ 2.304588821 ║
║ 5 ║ 207441663 ║ 89852249 ║ 2.308697504 ║
║ 6 ║ 223981096 ║ 106062643 ║ 2.111781205 ║
║ 7 ║ 275440586 ║ 125110111 ║ 2.201585338 ║
║ 8 ║ 327353547 ║ 145689642 ║ 2.246923958 ║
║ 9 ║ 363908633 ║ 163442675 ║ 2.226521519 ║
║ 10 ║ 407152133 ║ 181642026 ║ 2.241508433 ║
║ 11 ║ 445141584 ║ 197571786 ║ 2.25306251 ║
║ 12 ║ 495590201 ║ 217373350 ║ 2.279903222 ║
║ 13 ║ 520907684 ║ 236609850 ║ 2.201546909 ║
║ 14 ║ 511052601 ║ 217571474 ║ 2.348895246 ║
║ 15 ║ 610024381 ║ 260208969 ║ 2.344363391 ║
║ 16 ║ 637676317 ║ 275558318 ║ 2.314124725 ║
╚══════════════════════╩════════════════════╩════════════════════════╩═════════════╝
快 2 倍。
关于c# - DateTime.DayOfWeek 微优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22258070/
比较代码: const char x = 'a'; std::cout > (0C310B0h) 00C3100B add esp,4 和 const i
您好,我正在使用 Matlab 优化求解器,但程序有问题。我收到此消息 fmincon 已停止,因为目标函数值小于目标函数限制的默认值,并且约束满足在约束容差的默认值范围内。我也收到以下消息。警告:矩
处理Visual Studio optimizations的问题为我节省了大量启动和使用它的时间 当我必须进行 J2EE 开发时,我很难回到 Eclipse。因此,我还想知道人们是否有任何提示或技巧可
情况如下:在我的 Excel 工作表中,有一列包含 1-name 形式的条目。考虑到数字也可以是两位数,我想删除这些数字。这本身不是问题,我让它工作了,只是性能太糟糕了。现在我的程序每个单元格输入大约
这样做有什么区别吗: $(".topHorzNavLink").click(function() { var theHoverContainer = $("#hoverContainer");
这个问题已经有答案了: 已关闭11 年前。 Possible Duplicate: What is the cost of '$(this)'? 我经常在一些开发人员代码中看到$(this)引用同一个
我刚刚结束了一个大型开发项目。我们的时间紧迫,因此很多优化被“推迟”。既然我们已经达到了最后期限,我们将回去尝试优化事情。 我的问题是:优化 jQuery 网站时您要寻找的最重要的东西是什么。或者,我
所以我一直在用 JavaScript 编写游戏(不是网络游戏,而是使用 JavaScript 恰好是脚本语言的游戏引擎)。不幸的是,游戏引擎的 JavaScript 引擎是 SpiderMonkey
这是我在正在构建的页面中使用的 SQL 查询。它目前运行大约 8 秒并返回 12000 条记录,这是正确的,但我想知道您是否可以就如何使其更快提出可能的建议? SELECT DISTINCT Adve
如何优化这个? SELECT e.attr_id, e.sku, a.value FROM product_attr AS e, product_attr_text AS a WHERE e.attr
我正在使用这样的结构来测试是否按下了所需的键: def eventFilter(self, tableView, event): if event.type() == QtCore.QEven
我正在使用 JavaScript 从给定的球员列表中计算出羽毛球 double 比赛的所有组合。每个玩家都与其他人组队。 EG。如果我有以下球员a、b、c、d。它们的组合可以是: a & b V c
我似乎无法弄清楚如何让这个 JS 工作。 scroll function 起作用但不能隐藏。还有没有办法用更少的代码行来做到这一点?我希望 .down-arrow 在 50px 之后 fade out
我的问题是关于用于生产的高级优化级联样式表 (CSS) 文件。 多么最新和最完整(准备在实时元素中使用)的 css 优化器/最小化器,它们不仅提供删除空格和换行符,还提供高级功能,如删除过多的属性、合
我读过这个: 浏览器检索在 中请求的所有资源开始呈现 之前的 HTML 部分.如果您将请求放在 中section 而不是,那么页面呈现和下载资源可以并行发生。您应该从 移动尽可能多的资源请求。
我正在处理一些现有的 C++ 代码,这些代码看起来写得不好,而且调用频率很高。我想知道我是否应该花时间更改它,或者编译器是否已经在优化问题。 我正在使用 Visual Studio 2008。 这是一
我正在尝试使用 OpenGL 渲染 3 个四边形(1 个背景图,2 个 Sprite )。我有以下代码: void GLRenderer::onDrawObjects(long p_dt) {
我确实有以下声明: isEnabled = false; if(foo(arg) && isEnabled) { .... } public boolean foo(arg) { some re
(一)深入浅出理解索引结构 实际上,您可以把索引理解为一种特殊的目录。微软的SQL SERVER提供了两种索引:聚集索引(clustered index,也称聚类索引、簇集索引)和非聚集索引(no
一、写在前面 css的优化方案,之前没有提及,所以接下来进行总结一下。 二、具体优化方案 2.1、加载性能 1、css压缩:将写好的css进行打包,可以减少很多的体积。 2、css单一样式:在需要下边
我是一名优秀的程序员,十分优秀!