跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • 关于 for 循环中的 j – 1>=0 和 j > 0 的效率问题,太诡异了
未分類
9 11 月 2020

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

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

資深大佬 : GTD 6

先看图,先用 j > 0 跑选择排序 关于 for 循环中的 j - 1>=0 和 j > 0 的效率问题,太诡异了

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

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

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

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

大佬有話說 (19)

  • 資深大佬 : xuanbg

    >=难道没有多跑一次吗?

  • 主 資深大佬 : GTD

    @xuanbg #1 我跑了 30 多次,都是差不多一样,一个是 17 秒 一个是 16 秒

  • 主 資深大佬 : GTD

    @xuanbg #1 哦哦,你说>=效率低一点,会多跑一次吗?

  • 資深大佬 : chendy

    代码发出来大家试试?

  • 資深大佬 : v2yybb

    j-1>=0;每次都计算 j-1,然后才判断.
    j>0 的话 每次只判断

  • 資深大佬 : xiangyuecn

    你理想中认为编译器是智能的,实机上编译器是一个智障。

  • 資深大佬 : chendy

    多了一步减法,字节码多了一条 isub
    大于小于 和 大于等于 小于等于 都是一条字节码,没区别

  • 資深大佬 : JeffGe

    你要说 j – 1 >= 0 快,才叫诡异吧

  • 資深大佬 : no1xsyzy

    ( JVM 不清楚,按对 C – asm 的理解应该差不多吧)
    j – 1 >= 0 是
    取 j,取 1,相减,取 0,比较并跳转
    j > 0 是
    取 j,取 0,比较并跳转
    即使理论上等效,但目前所有优化都是启发式的,不一定能发现最优解

  • 資深大佬 : guixiexiezou

    所有 java 相关的,建议都热身后再跑测试,不然和你预想的有很大不一样

  • 資深大佬 : dazhangpan

    不负责任地瞎猜是在分支条件这里的逻辑影响了 CPU 分支预测器的正确率
    可以用 perf 抓一下看看 mispredict 的比例是不是上升了

  • 資深大佬 : lakehylia

    试试 j – 1 >= 0 改成 j >= 1,看看时间是不是一样的。

  • 主 資深大佬 : GTD

    @lakehylia #12 不行,刚刚试了一下,j >=1 还是一样,只有改成 j>0 才能 16s 左右

  • 資深大佬 : Mohanson

    判断 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

    显然 j – 1 >= 0 和 j > 0 是完全不同的意思,因为 Java 规定有符号数的溢出行为。如果 j = -2147483648,那么 j – 1 >= 0 是 true 而 j > 0 是 false 。

    因此,编译器很难进行优化,故会采用先减后判断符号的方式,多做一次减法当然会慢。

  • 資深大佬 : lakehylia

    @GTD 那结果就明显了,编译器在变量跟 0 的对比上有优化,而其他值没有。

  • 資深大佬 : misaka19000

    直接看编译后的字节码,对比区别

  • 資深大佬 : XuanFei990

    我以为下边的会短呢,那才奇怪。
    多了一步减法操作吧,循环次数少,没什么感觉,循环次数多的话就产生明显差异了

  • 資深大佬 : Yantc

    @GTD

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

    显然第二种情况快啊

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具