前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java源码解读 – 常量52429

Java源码解读 – 常量52429

作者头像
KAAAsS
发布2022-01-14 18:07:53
4760
发布2022-01-14 18:07:53
举报
文章被收录于专栏:KAAAsS's Blog

本篇文章最早源于我在知乎的回答,传送门

52429作为常量经常出现在openjava中openjdk8-b132的java.lang.Integer类的456行为例子:

代码语言:javascript
复制
// Fall thru to fast mode for smaller numbers
// assert(i <= 65536, i);
for (;;) {
    q = (i * 52429) >>> (16+3);
    r = i - ((q << 3) + (q << 1));  // r = i-(q*10) ...
    buf [--charPos] = digits [r];
    i = q;
    if (i == 0) break;
}

固定的形式是一个整型变量乘上52429,然后向右移19位。很自然想到2^19=524288,那么这个52429就不难理解了,应该就是除10的操作。除法是很慢的,而乘法和以为却相对较快,所以为了优化这一点点的速度,java采用了乘52429再移19位的方法。对于为什么选择52429,这里列出几个取值的精度:

103/1024≈0.1006 (2^10) 205/2048≈0.100098 (2^11) …… 26215/262144≈0.100002 (2^18) 52429/524288≈0.10000038 (2^19) 104858/1048576≈0.10000038 (2^20)

可见,到2^19次方左右,除10的精度已经非常高了。那么为什么不再选几位呢?原因很简单:首先就是,java中整型占32位,而52429的二进制是1100110011001101(16位),65535的二进制是111111111111111(16位),相乘结果为31位。通过阅读上述源码的这个方法可知,i是不会大于65535的(注释中也提到:assert(i <= 65536, i);),所以算上符号位,能达到精度最大而又不溢出的也就是2^19了。

后记

Sun公司的程序员对java的性能优化是非常仔细且彻底的,这一点在阅读openjdk的时候相信肯定会体会到。对于本文中除法的优化,按照现今计算平台来看,说实在的,几乎是没有效果的。但是java还是做了优化。在阅读openjdk的时候,还会遇到很多类似的东西,这时候就应该多多思考:这些代码有什么用?能不能换成别的?这样,相信对java也会有更深的理解。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017/06 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 后记
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档