关于 for 循环中的 j - 1>=0 和 j > 0 的效率问题,太诡异了

2020 年 11 月 12 日
 GTD

先看图,先用 j > 0 跑选择排序

然后改成 j - 1 >= 0,继续测试选择排序

这个算法一模一样,什么都没改,我跑了 30 多次,每次用 j - 1 > =0 都是 17 秒左右,而用 j >0 都在 16 秒左右,这两个效率怎么会有这么大差别,不应该啊。

而且我跑了 30 多次,每次都一样,一个是 16 秒,一个是 17 秒,只是小数点后不一样而已

4506 次点击
所在节点    Java
19 条回复
xuanbg
2020 年 11 月 12 日
>=难道没有多跑一次吗?
GTD
2020 年 11 月 12 日
@xuanbg #1 我跑了 30 多次,都是差不多一样,一个是 17 秒 一个是 16 秒
GTD
2020 年 11 月 12 日
@xuanbg #1 哦哦,你说>=效率低一点,会多跑一次吗?
chendy
2020 年 11 月 12 日
代码发出来大家试试?
v2yybb
2020 年 11 月 12 日
j-1>=0;每次都计算 j-1,然后才判断.
j>0 的话 每次只判断
xiangyuecn
2020 年 11 月 12 日
你理想中认为编译器是智能的,实机上编译器是一个智障。
chendy
2020 年 11 月 12 日
多了一步减法,字节码多了一条 isub
大于小于 和 大于等于 小于等于 都是一条字节码,没区别
JeffGe
2020 年 11 月 12 日
你要说 j - 1 >= 0 快,才叫诡异吧
no1xsyzy
2020 年 11 月 12 日
( JVM 不清楚,按对 C - asm 的理解应该差不多吧)
j - 1 >= 0 是
取 j,取 1,相减,取 0,比较并跳转
j > 0 是
取 j,取 0,比较并跳转
即使理论上等效,但目前所有优化都是启发式的,不一定能发现最优解
guixiexiezou
2020 年 11 月 12 日
所有 java 相关的,建议都热身后再跑测试,不然和你预想的有很大不一样
dazhangpan
2020 年 11 月 12 日
不负责任地瞎猜是在分支条件这里的逻辑影响了 CPU 分支预测器的正确率
可以用 perf 抓一下看看 mispredict 的比例是不是上升了
lakehylia
2020 年 11 月 12 日
试试 j - 1 >= 0 改成 j >= 1,看看时间是不是一样的。
GTD
2020 年 11 月 12 日
@lakehylia #12 不行,刚刚试了一下,j >=1 还是一样,只有改成 j>0 才能 16s 左右
Mohanson
2020 年 11 月 12 日
判断 j > 0 在 x86 上智商正常的编译器会用 jns 指令(Jump if not sign)而不会用比较跳转指令, 判断条件是 SF = 0

判断 j >= 1 在 x86 上用的是 jg 指令(Jump if greater), 判断条件是 ZF = 0 and SF = OF

以上是 gcc 的逻辑(我完全不会 java 也不知道 jvm 到底怎么操作的)
geelaw
2020 年 11 月 12 日
显然 j - 1 >= 0 和 j > 0 是完全不同的意思,因为 Java 规定有符号数的溢出行为。如果 j = -2147483648,那么 j - 1 >= 0 是 true 而 j > 0 是 false 。

因此,编译器很难进行优化,故会采用先减后判断符号的方式,多做一次减法当然会慢。
lakehylia
2020 年 11 月 12 日
@GTD 那结果就明显了,编译器在变量跟 0 的对比上有优化,而其他值没有。
misaka19000
2020 年 11 月 12 日
直接看编译后的字节码,对比区别
XuanFei990
2020 年 11 月 12 日
我以为下边的会短呢,那才奇怪。
多了一步减法操作吧,循环次数少,没什么感觉,循环次数多的话就产生明显差异了
Yantc
2020 年 11 月 12 日
@GTD

j >=1:先做 j-1,再将 j-i 后的 ans 和 0 判断大小还要看是否存在溢出
j>0:直接将 j 的 bit 位或起来,就直接可判断,1:则 j 大于 0,0:则 j==0.

显然第二种情况快啊

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://v2ex.ih06.com/t/724368

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX