奇怪?为什么 floor((n + t - 1) / t) 比 ceil(n / t) 更高效?(因为没有浮点转换带来的性能损耗)

为什么 (n + t - 1) // tceil(n / t) 更高效?

导言

在刷leetcode的时候,发现了用 (n + t - 1) / t替换ceil(n/t)从而带来的性能优化

原理:(因为没有浮点转换带来的性能损耗)

在处理数组分块、分页计算等场景时,我们经常需要计算向上取整的除法。例如,将长度为103的数组分成长度为10的块,需要计算ceil(103/10)=11

常见的实现方式有两种:

  1. 直接向上取整:math.ceil(n / t)
    • math.ceil(103/10)=11
  2. 整数运算模拟:(n + t - 1) // t(这里//表示纯整数除法)
    • (103+10-1)//t=11

虽然结果相同,但后者在多数情况下更高效(因为没有浮点转换带来的性能损耗)。

数学原理(太妙啦啦啦啦啦啦啦啦啦)

偏移量设计

选择t-1作为偏移量的原因:

  1. 当n能被t整除时​(余数r=0):

    • n = k*t
    • (n + t - 1) // t = (k*t + t - 1) // t = k + (t-1)//t = k(正确)
  2. 当n不能被t整除时​(余数r≥1):

    • n = k*t + r
    • (n + t - 1) // t = (k*t + r + t - 1) // t = k + (r + t - 1)//t = k + 1(正确)

示例验证

python 复制代码
# 整除情况
(4 + 2 - 1) // 2 = 5 // 2 = 2  # 等同于ceil(4/2)
# 非整除情况
(5 + 2 - 1) // 2 = 6 // 2 = 3  # 等同于ceil(5/2)

性能分析

ceil(n / t)的问题

大多数语言在实现这个函数的时候,内部都会使用强制浮点运算

  1. 强制浮点运算​:

    • 整数→浮点转换
    • 浮点除法
    • 浮点取整

强制浮点运算会带来性能损耗

(n + t - 1) // t的优势

这里的//在python中表示纯整数除法

python 复制代码
sum = (103+10-1)//10 = 11

在java或者C/C++中只要类型是int,计算除法的时候就会触发纯整数除法

java 复制代码
int sum = (103+10-1)/10 = 11
  1. 纯整数运算​:

    • 直接使用CPU整数除法指令
    • 无类型转换开销

更稳定不受浮点精度限制,需要纯整数运算支持,例如下面的语言

语言特性差异

语言 推荐写法 原因
C/C++/Java (n + t - 1) / t 整数除法直接截断
Python (n + t - 1) // t //避免浮点运算
JavaScript/TS Math.ceil(n / t) JS和TS中的所有除法都是浮点运算,使用Math.ceil可读性优先
高性能场景 (n + t - 1) >> k (t=2^k) 位运算最快

建议

  1. 优先考虑整数运算​:

    • 在支持整数除法的语言中使用(n + t - 1) // t
  2. 可读性与性能平衡​:

    • 在JS/TS等语言中,Math.ceil的可读性更佳
  3. 特殊场景优化​:

    • 当除数为2的幂次时,可用位运算进一步优化
  4. 避免过早优化​:

    • 非性能关键路径可优先考虑代码可读性

总结

(n + t - 1) // t通过巧妙的数学设计,在多数编程语言中实现了:

  • 更高效的纯整数运算
  • 避免浮点转换开销
  • 更好的大数稳定性

6666666666666666666

相关推荐
炫饭第一名18 分钟前
速通Canvas指北🦮——基础入门篇
前端·javascript·程序员
王晓枫35 分钟前
flutter接入三方库运行报错:Error running pod install
前端·flutter
符方昊35 分钟前
React 19 对比 React 16 新特性解析
前端·react.js
ssshooter40 分钟前
又被 Safari 差异坑了:textContent 拿到的值居然没换行?
前端
开心就好20251 小时前
UniApp开发应用多平台上架全流程:H5小程序iOS和Android
后端·ios
曲折1 小时前
Cesium-气象要素PNG色斑图叠加
前端·cesium
悟空码字1 小时前
告别“屎山代码”:AI 代码整洁器让老项目重获新生
后端·aigc·ai编程
Forever7_1 小时前
Electron 淘汰!新的桌面端框架 更强大、更轻量化
前端·vue.js
小码哥_常1 小时前
大厂不宠@Transactional,背后藏着啥秘密?
后端
Angelial1 小时前
Vue3 嵌套路由 KeepAlive:动态缓存与反向配置方案
前端·vue.js