【发布时间】:2012-07-05 12:00:09
【问题描述】:
This guy 声称二进制搜索(在 C 编译器中)比从生成的代码中硬编码的 if 分支慢。 (请原谅 Clojure 代码和古怪的标题 - 这声称这个人所做的通常与编译器有关)。
他写
我偶尔会在黑暗的角落看到这种代码。当一个男人知道 他的处理器如何工作,知道他的 C 编译器如何工作,知道他的数据 结构,真的,真的需要他的循环速度很快,然后他会 偶尔写这种东西。
这是真正的程序员编写的代码。
这是二分搜索示例(请原谅 Clojure)
Start: (1 2 3 4 6 8 9 10 11 12)
Finish: ((((1) (2)) ((3) ((4) (6)))) (((8) (9)) ((10) ((11) (12)))))
然后,他将二进制搜索替换为生成的代码,如果基于硬编码值进行分支:
(defn lookup-fn-handwritten [x]
(if (< x 6)
(if (< x 3) ; x is < 6
(if (< x 2) ; x is < 3
(if ( < x 1) ; x is < 2
0 ; < 1
1) ; 1 <= x < 2
3) ; 2 <= x < 3
(if (< x 4) ; 3 <= x < 6
4 ; 3 <= x < 4
2)) ; 4 <= x < 6
(if (< x 10) ; 6 <= x < 10
(if (< x 9) ; 6 <= x < 9
(if (< x 8)
2 ; 6 <= x < 8
3) ; 8 <= x < 9
3) ; 9 <= x < 10
(if (< x 11) ; 10 < x
(if (< x 12) ; 11 <= x
1 ; 11 <= x < 12
0)
0)))) ; 12 <= x
http://www.learningclojure.com/2010/09/clojure-faster-than-machine-code.html
我的问题是 - 如果从生成的代码和硬编码值中进行分支硬编码是否比二进制搜索更有效? (在任何语言中 - 但作者声称这在 C 中有效 - 然后似乎只在 JVM 上演示它)。
(请再次原谅链接帖子的古怪标题 - 这只是疯狂。)
【问题讨论】:
-
他的标题没有错,可以说一个好的算法总有一天会毁掉一个坏算法的手工优化汇编版本。
-
这并不是什么特别的说法……
-
对于这么小的集合,数组查找或 switch 语句会更快,它的
O(1)