使用新颖的历法算法进行优化

这是一篇关于优化time crate 中Date::to_calendar_date方法的文章,主要内容总结如下:

  • 背景:作者维护time crate 五年,代码量有增有减,虽有基准测试但未真正优化,现决定进行性能审计,因其不在优先事项中且需大量努力,而作者想做不同的事。
  • 起始点:基于对已知算法使用位置等的了解,选定Date::to_calendar_date方法作为优化起点。
  • 现状:原实现简单,通过查找表确定月份和天数,先判断是否为闰年确定查找表,再通过一系列if语句确定月份和天数。考虑过用二进制搜索和循环替代if语句,但前者表小搜索成本高,后者 Rust 优化困难性能更差。
  • 设计新算法:作者从未从头写过日期时间算法,受 Cassio Neri 和 Lorenz Schneider 的论文启发,决定尝试使用欧几里得仿射函数,设计新算法时遵循正确性、性能、仅用整数、const兼容等原则。
  • 计算月份:通过可视化和电子表格辅助,先确定一月和二月的总天数,根据总天数调整序数,再用平均月长近似计算月份,最后通过修正得到准确月份,将其转化为代码。
  • 计算天数:在计算出月份后,通过添加更多列到电子表格,利用平均月长计算前几个月的累积天数,再用序数减去该累积天数得到天数,将其转化为代码。
  • 初步比较:比较原实现和新实现的生成汇编代码,新实现指令更少且无分支,MCA 分析显示新实现在总周期等方面更优,但也有一些局限性。
  • 进一步改进:对月份和天数计算进行优化,如分配乘法、利用幂次优化除法等,还调整了代码中的类型转换以避免溢出。
  • 最终代码:经过一系列优化后的最终代码,其性能比原实现快 57.5%,且是分支无的、const兼容的,生成的汇编代码中包含优化后的常量。
  • 基准测试:使用criterion进行基准测试,新实现在所有 24 个值上的计算时间都比原实现快,单计算时间分别快 3.1698ns、1.7900ns、1.3487ns。
  • 截断算法:新算法在单独计算月份和天数时也更快,分别比原实现快 43.2%和 48.1%,提供了相应代码、生成的汇编代码和基准测试结果。
  • 总结:成功创建了性能更好的算法,未来希望创建更多这样的算法,虽耗时但对实际应用有显著影响。
阅读 32
0 条评论