我正在研究 Collatz 猜想(见下文),并且我有这个函数:
\nfunction txpo(max_n)\n for n \xe2\x88\x88 1:max_n\n x = n\n while x \xe2\x89\xa5 n && x != 1\n x = iseven(x) ? x\xc3\xb72 : 3x+1\n end\n end\nend\nRun Code Online (Sandbox Code Playgroud)\n我故意不返回任何东西或检查任何东西,以使其尽可能快。天哪,速度快吗... - 实际上太快了,我想。
\nusing BenchmarkTools\n@btime txpo(100_000_000_000_000_000_000_000_000_000_000_000_000)\n\n2.337 ns (0 allocations: 0 bytes)\nRun Code Online (Sandbox Code Playgroud)\n运行10^38个while循环只需要2ns?朱莉娅很快,但如果有那么快我会感到惊讶。看起来代码没有被评估。或者我在这里缺少什么?
Collatz 猜想\n取一个整数并使用以下规则构建一个级数:如果该数字是偶数除以 2;如果数字是奇数乘以3并加1。猜想:每个系列都会进入循环4-2-1-4。
事实上,整个函数体都被优化了:
\njulia> function txpo(max_n)\n for n \xe2\x88\x88 1:max_n\n x = n\n while x \xe2\x89\xa5 n && x != 1\n x = iseven(x) ? x\xc3\xb72 : 3x+1\n end\n end\n end\ntxpo (generic function with 1 method)\n\njulia> @code_llvm txpo(100000000000)\n; @ REPL[1]:1 within `txpo`\ndefine void @julia_txpo_179(i64 signext %0) #0 {\ntop:\n; @ REPL[1]:5 within `txpo`\n ret void\n}\nRun Code Online (Sandbox Code Playgroud)\n如果你使用10^38,这只会更改函数签名以接受 128 位整数。
LLVM IR 代码与以下 Julia 代码基本相同:
\njulia_txpo_179(_0::Int64) = nothing\nRun Code Online (Sandbox Code Playgroud)\n这是完全有道理的,因为为什么要执行一个不返回任何依赖于其计算且没有副作用的函数?
\n最后,CPU 执行的本机代码实际上是retq“返回调用者”:
julia> @code_native txpo(100000000000)\n .section __TEXT,__text,regular,pure_instructions\n; \xe2\x94\x8c @ REPL[1]:5 within `txpo`\n retq\n nopw %cs:(%rax,%rax)\n; \xe2\x94\x94\n\njulia> \nRun Code Online (Sandbox Code Playgroud)\n