tilldream 发表于 2019-3-14 19:18:47

碾压 Python!为什么 Julia 速度这么快?

<section class=""></section><p style="margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px; max-width: 100%; color: rgb(0, 0, 0); letter-spacing: 0.5px; box-sizing: border-box !important;"><br></span></p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px;letter-spacing: 0.5px;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica="" neue",="" "pingfang="" sc",="" "hiragino="" sans="" gb",="" "microsoft="" yahei="" ui",="" yahei",="" arial,="" sans-serif;"="">为什么要选择 Julia?因为它比其他脚本语言更快,它在具备 Python、MATLAB、R 语言开发速度的同时,又能生成与 C 语言和 Fortran 一样快的代码。</span><br></p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px;letter-spacing: 0.5px;font-family: -apple-system-font, BlinkMacSystemFont, " helvetica="" neue",="" "pingfang="" sc",="" "hiragino="" sans="" gb",="" "microsoft="" yahei="" ui",="" yahei",="" arial,="" sans-serif;"=""><br></span></p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px;letter-spacing: 0.5px;">但 Julia 新手对这种说法可能会有点怀疑。&nbsp;</span></p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px;letter-spacing: 0.5px;">&nbsp;</span></p><ol class=" list-paddingleft-2" style="margin-left: 8px;margin-right: 8px;"><li><p style="line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">为什么其他脚本语言不也提升一下速度?Julia 可以做到的,为什么其他脚本语言做不到?</span></p></li><li><p style="line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">你能提供基准测试来证明它的速度吗?</span></p></li><li><p style="line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">这似乎有违 “天底下没有免费的午餐” 的道理。它真的有那么完美吗?</span></p></li></ol><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px;letter-spacing: 0.5px;">很多人认为 Julia 运行速度很快,因为它是<strong>即时编译</strong>(JIT)型的(也就是说,每条语句都使用编译的函数来运行,这些函数要么在使用之前进行即时编译,要么在之前已经编译过并放在缓存中)。这就引出了一个问题:Julia 是否提供了比 Python 或 R 语言(MATLAB 默认使用 JIT)更好的 JIT 实现?因为人们在这些 JIT 编译器上所做的工作比 Julia 要多得多,所以我们凭什么认为 Julia 这么快就会超过这些编译器?但其实这完全是对 Julia 的误解。</span></p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px;letter-spacing: 0.5px;">我想以一种非常直观的方式说明,<strong>Julia 的速度之所以快,是因为它的设计决策</strong>。Julia 的的核心设计决策是通过多重分派实现专门化的类型稳定性,编译器因此可以很容易地生成高效的代码,同时还能够保持代码的简洁,让它 “<strong>看起来就像一门脚本语言</strong>”。</span></p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px;letter-spacing: 0.5px;">但是,在本文的示例中,我们将看到 Julia 并不总是像其他脚本语言那样,我们必须接受 “午餐不全是免费” 的事实。</span></p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px;letter-spacing: 0.5px;">要看出它们之间的区别,我们只需要看看基本的数学运算。</span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><section style="border-width: 0px;border-style: initial;border-color: initial;clear: both;box-sizing: border-box;" class="tn-Powered-by-XIUMI"><section style="padding: 8px;border-left: 6px solid rgb(255, 202, 0);font-size: 112.5%;line-height: 1.4;font-family: inherit;font-weight: bold;text-decoration: inherit;color: rgb(10, 10, 10);border-top-color: rgb(255, 202, 0);border-right-color: rgb(255, 202, 0);border-bottom-color: rgb(255, 202, 0);box-sizing: border-box;" class="tn-Powered-by-XIUMI"><section class="tn-Powered-by-XIUMI">Julia 中的数学运算<br></section></section></section><p><span style="letter-spacing: 0.5px;font-size: 15px;"><br></span></p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="letter-spacing: 0.5px;font-size: 15px;">一般来说,Julia 中的数学运算与其他脚本语言中的数学运算看起来是一样的。它们的数字都是 “真正的数字”,比如 Float64 就是 64 位浮点数或者类似于 C 语言中的 “double”。Vector {Float64} 与 C 语言 double 数组的内存布局是一样的,都可以很容易地与 C 语言进行互操作(实际上,在某种意义上,“Julia 是构建在 C 语言之上的一个层”),从而带来更高的性能。</span></p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="letter-spacing: 0.5px;font-size: 15px;"><br></span></p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="letter-spacing: 0.5px;font-size: 15px;">使用 Julia 进行一些数学运算:</span>&nbsp;</p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><br></p><section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="" mpa-preserve="t" style="max-width: 100%; color: rgb(63, 63, 63); font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; box-sizing: border-box !important;"><pre style="max-width: 100%; background: none; box-sizing: border-box !important;"><code class="" style="margin-right: 0.15em; margin-left: 0.15em; padding: 5.95px; max-width: 100%; border-radius: 4px; font-size: 0.85em; background: rgb(40, 44, 52); color: rgb(171, 178, 191); display: block; overflow-x: auto; white-space: nowrap; box-sizing: border-box !important;">a =&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">2</span>+<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">2</span><br style="max-width: 100%; box-sizing: border-box !important;">b = a/<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">3</span><br style="max-width: 100%; box-sizing: border-box !important;">c = a÷<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">3</span>&nbsp;<span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 288px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">#\div tab completion, means integer division</span><br style="max-width: 100%; box-sizing: border-box !important;">d =&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">4</span>*<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">5</span><br style="max-width: 100%; box-sizing: border-box !important;">println()<br style="max-width: 100%; box-sizing: border-box !important;"><br style="max-width: 100%; box-sizing: border-box !important;">[<span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 151px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">4.0, 1.33333, 1.0, 20.0</span>]</code></pre></section><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="letter-spacing: 0.5px;font-size: 15px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="letter-spacing: 0.5px;font-size: 15px;">我在这里使用了 Julia 的 unicode 制表符补全功能。Julia 允许使用 unicode 字符,这些字符可以通过制表符实现 Latex 风格的语句。同样,如果一个数字后面跟着一个变量,那么不需要使用 * 运算符就可以进行乘法运算。例如,下面的 Julia 的代码是合法的:</span>&nbsp;</p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><br></p><section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="" mpa-preserve="t" style="max-width: 100%; color: rgb(63, 63, 63); font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; box-sizing: border-box !important;"><pre style="max-width: 100%; background: none; box-sizing: border-box !important;"><code class="" style="margin-right: 0.15em; margin-left: 0.15em; padding: 5.95px; max-width: 100%; border-radius: 4px; font-size: 0.85em; background: rgb(40, 44, 52); color: rgb(171, 178, 191); display: block; overflow-x: auto; white-space: nowrap; box-sizing: border-box !important;">α =&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 19px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">0.5</span><br style="max-width: 100%; box-sizing: border-box !important;">∇f(u) = α*u; ∇f(<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">2</span>)<br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(230, 192, 123); background: rgba(0, 0, 0, 0); display: inline; width: 19px; text-decoration-style: solid; text-decoration-color: rgb(230, 192, 123); box-sizing: border-box !important;">sin</span>(<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">2</span>π)<br style="max-width: 100%; box-sizing: border-box !important;"><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 150px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">-2.4492935982947064e-16</span></code></pre></section><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="letter-spacing: 0.5px;font-size: 15px;"><br></span></p><section style="border-width: 0px;border-style: initial;border-color: initial;clear: both;box-sizing: border-box;" class="tn-Powered-by-XIUMI"><section style="padding: 8px;border-left: 6px solid rgb(255, 202, 0);font-size: 112.5%;line-height: 1.4;font-family: inherit;font-weight: bold;text-decoration: inherit;color: rgb(10, 10, 10);border-top-color: rgb(255, 202, 0);border-right-color: rgb(255, 202, 0);border-bottom-color: rgb(255, 202, 0);box-sizing: border-box;" class="tn-Powered-by-XIUMI"><section class="tn-Powered-by-XIUMI">类型稳定性和代码内省<br></section></section></section><p><span style="letter-spacing: 0.5px;font-size: 15px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="letter-spacing: 0.5px;font-size: 15px;">类型稳定性是指一个方法<strong>只能输出一种可能的类型</strong>。例如:*(::Float64,::Float64) 输出的类型是 Float64。不管你给它提供什么参数,它都会返回一个 Float64。这里使用了多重分派:“*” 操作符根据它看到的类型调用不同的方法。例如,当它看到浮点数时,就会返回浮点数。Julia 提供了代码自省宏,可以看到代码被编译成什么东西。因此,Julia 不只是一门普通的脚本语言,还是一门可以让你<strong>处理汇编</strong>的脚本语言!和其他很多语言一样,Julia 被编译成 LLVM (LLVM 是一种可移植的汇编格式)。</span>&nbsp;</p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><br></p><section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="" mpa-preserve="t" style="max-width: 100%; color: rgb(63, 63, 63); font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; box-sizing: border-box !important;"><pre style="max-width: 100%; background: none; box-sizing: border-box !important;"><code class="" style="margin-right: 0.15em; margin-left: 0.15em; padding: 5.95px; max-width: 100%; border-radius: 4px; font-size: 0.85em; background: rgb(40, 44, 52); color: rgb(171, 178, 191); display: block; overflow-x: auto; white-space: nowrap; box-sizing: border-box !important;">@code_llvm&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">2</span>*<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">5</span><br style="max-width: 100%; box-sizing: border-box !important;"><br style="max-width: 100%; box-sizing: border-box !important;">;&nbsp;<span class="" style="max-width: 100%; background: rgba(0, 0, 0, 0); display: inline; width: 65px; text-decoration-style: solid; text-decoration-color: rgb(171, 178, 191); box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 53px;text-decoration-style: solid;text-decoration-color: rgb(198, 120, 221);">Function</span>&nbsp;*<br style="max-width: 100%; box-sizing: border-box !important;"></span>; Location: int.jl:<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">54</span><br style="max-width: 100%; box-sizing: border-box !important;">define i64 @<span class="" style="max-width: 100%; color: rgb(152, 195, 121); background: rgba(0, 0, 0, 0); display: inline; width: 98px; text-decoration-style: solid; text-decoration-color: rgb(152, 195, 121); box-sizing: border-box !important;">"julia_*_33751"</span>(i64, i64) {<br style="max-width: 100%; box-sizing: border-box !important;">top:<br style="max-width: 100%; box-sizing: border-box !important;">%<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">2</span>&nbsp;= mul i64 %<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">1</span>, %<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">0</span><br style="max-width: 100%; box-sizing: border-box !important;">ret i64 %<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">2</span><br style="max-width: 100%; box-sizing: border-box !important;">}</code></pre></section><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">这段代码的意思是:执行一个浮点数乘法操作,然后返回结果。我们也可以看一下汇编代码。</span>&nbsp;</p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><br></p><section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="" mpa-preserve="t" style="max-width: 100%; color: rgb(63, 63, 63); font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; box-sizing: border-box !important;"><pre style="max-width: 100%; background: none; box-sizing: border-box !important;"><code class="" style="margin-right: 0.15em; margin-left: 0.15em; padding: 5.95px; max-width: 100%; border-radius: 4px; font-size: 0.85em; background: rgb(40, 44, 52); color: rgb(171, 178, 191); display: block; overflow-x: auto; white-space: nowrap; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 78px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">@code_native</span>&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">2</span>*<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">5</span><br style="max-width: 100%; box-sizing: border-box !important;"><br style="max-width: 100%; box-sizing: border-box !important;">.text<br style="max-width: 100%; box-sizing: border-box !important;">;&nbsp;<span class="" style="max-width: 100%; color: rgb(224, 108, 117); background: rgba(0, 0, 0, 0); display: inline; width: 53px; text-decoration-style: solid; text-decoration-color: rgb(224, 108, 117); box-sizing: border-box !important;">Function</span>&nbsp;* {<br style="max-width: 100%; box-sizing: border-box !important;">;&nbsp;<span class="" style="max-width: 100%; color: rgb(152, 195, 121); background: rgba(0, 0, 0, 0); display: inline; width: 53px; text-decoration-style: solid; text-decoration-color: rgb(152, 195, 121); box-sizing: border-box !important;">Location</span>: int.<span class="" style="max-width: 100%; color: rgb(152, 195, 121); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(152, 195, 121); box-sizing: border-box !important;">jl</span>:<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">54</span><br style="max-width: 100%; box-sizing: border-box !important;">imulq %rsi, %rdi<br style="max-width: 100%; box-sizing: border-box !important;">movq %rdi, %rax<br style="max-width: 100%; box-sizing: border-box !important;">retq<br style="max-width: 100%; box-sizing: border-box !important;">nopl (%rax,%rax)<br style="max-width: 100%; box-sizing: border-box !important;">;}</code></pre></section><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">“*” 函数被编译成与 C 语言或 Fortran 中完全相同的操作,这意味着它可以达到相同的性能(尽管它是在 Julia 中定义的)。因此,Julia 不仅可以 “接近” C 语言,而且实际上可以得到相同的 C 语言代码。那么在什么情况下会发生这种情况?</span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">Julia 的有趣之处在于,上面的这个问题其实问得不对,正确的问题应该是:在什么情况下代码不能被编译成像 C 语言或 Fortran 那样?这里的关键是类型稳定性。如果一个函数是类型稳定的,那么编译器就会知道函数在任意时刻的类型,就可以巧妙地将其优化为与 C 语言或 Fortran 相同的汇编代码。如果它不是类型稳定的,Julia 必须进行昂贵的 “装箱”,以确保在操作之前知道函数的类型是什么。</span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="color: rgb(255, 104, 39);"><strong><span style="font-size: 15px;letter-spacing: 0.5px;">这是 Julia 与其他脚本语言之间最关键的不同点。</span></strong></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">好的方面是 Julia 的函数(类型稳定)基本上就是 C 语言或 Fortran 的函数,因此 “^”(乘方)运算速度很快。那么,类型稳定的 ^(::Int64,::Int64) 会输出什么?</span>&nbsp;</p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><br></p><section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="" mpa-preserve="t" style="max-width: 100%; color: rgb(63, 63, 63); font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; box-sizing: border-box !important;"><pre style="max-width: 100%; background: none; box-sizing: border-box !important;"><code class="" style="margin-right: 0.15em; margin-left: 0.15em; padding: 5.95px; max-width: 100%; border-radius: 4px; font-size: 0.85em; background: rgb(40, 44, 52); color: rgb(171, 178, 191); display: block; overflow-x: auto; white-space: nowrap; box-sizing: border-box !important;">2^5<br style="max-width: 100%; box-sizing: border-box !important;"><br style="max-width: 100%; box-sizing: border-box !important;">32</code></pre></section><p><br style="max-width: 100%; box-sizing: border-box !important;"></p><section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="" mpa-preserve="t" style="max-width: 100%; color: rgb(63, 63, 63); font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; box-sizing: border-box !important;"><pre style="max-width: 100%; background: none; box-sizing: border-box !important;"><code class="" style="margin-right: 0.15em; margin-left: 0.15em; padding: 5.95px; max-width: 100%; border-radius: 4px; font-size: 0.85em; background: rgb(40, 44, 52); color: rgb(171, 178, 191); display: block; overflow-x: auto; white-space: nowrap; box-sizing: border-box !important;">2^<span class="" style="max-width: 100%; color: rgb(224, 108, 117); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(224, 108, 117); box-sizing: border-box !important;">-5</span><br style="max-width: 100%; box-sizing: border-box !important;"><br style="max-width: 100%; box-sizing: border-box !important;">0<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 39px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">.03125</span></code></pre></section><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">这里我们会得到一个错误。为了确保编译器可以为 “^” 返回一个 Int64,它必须抛出一个错误。但在 MATLAB、Python 或 R 语言中这么做是不会抛出错误的,因为这些语言没有所谓的类型稳定性。</span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">如果没有类型安全性会怎样?让我们看一下代码:</span>&nbsp;</p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><br></p><section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="" mpa-preserve="t" style="max-width: 100%; color: rgb(63, 63, 63); font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; box-sizing: border-box !important;"><pre style="max-width: 100%; background: none; box-sizing: border-box !important;"><code class="" style="margin-right: 0.15em; margin-left: 0.15em; padding: 5.95px; max-width: 100%; border-radius: 4px; font-size: 0.85em; background: rgb(40, 44, 52); color: rgb(171, 178, 191); display: block; overflow-x: auto; white-space: nowrap; box-sizing: border-box !important;">@code_native ^(<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">2</span>,<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">5</span>)<br style="max-width: 100%; box-sizing: border-box !important;"><br style="max-width: 100%; box-sizing: border-box !important;">.text<br style="max-width: 100%; box-sizing: border-box !important;">; Function ^ {<br style="max-width: 100%; box-sizing: border-box !important;">; Location: intfuncs.jl:<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 19px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">220</span><br style="max-width: 100%; box-sizing: border-box !important;">pushq %rax<br style="max-width: 100%; box-sizing: border-box !important;">movabsq&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 117px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">$power_by_squaring</span>, %rax<br style="max-width: 100%; box-sizing: border-box !important;">callq *%rax<br style="max-width: 100%; box-sizing: border-box !important;">popq %rcx<br style="max-width: 100%; box-sizing: border-box !important;">retq<br style="max-width: 100%; box-sizing: border-box !important;">nop<br style="max-width: 100%; box-sizing: border-box !important;">;}</code></pre></section><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">现在,我们来定义自己的整数乘方运算。与其他脚本语言一样,我们让它变得更 “安全”:</span>&nbsp;</p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><br></p><section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="" mpa-preserve="t" style="max-width: 100%; color: rgb(63, 63, 63); font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; box-sizing: border-box !important;"><pre style="max-width: 100%; background: none; box-sizing: border-box !important;"><code class="" style="margin-right: 0.15em; margin-left: 0.15em; padding: 5.95px; max-width: 100%; border-radius: 4px; font-size: 0.85em; background: rgb(40, 44, 52); color: rgb(171, 178, 191); display: block; overflow-x: auto; white-space: nowrap; box-sizing: border-box !important;"><span class="" style="max-width: 100%; background: rgba(0, 0, 0, 0); display: inline; width: 117px; text-decoration-style: solid; text-decoration-color: rgb(171, 178, 191); box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 52px;text-decoration-style: solid;text-decoration-color: rgb(198, 120, 221);">function</span>&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 26px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">expo</span><span class="" style="max-width: 100%;background: rgba(0, 0, 0, 0);display: inline;width: 33px;text-decoration-style: solid;text-decoration-color: rgb(171, 178, 191);">(x,y)</span></span><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">if</span>&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">y</span>&gt;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">0</span><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 39px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">return</span>&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">x</span>^<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">y</span><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 26px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">else</span><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">x</span>&nbsp;= convert(Float64,<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">x</span>)<br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 39px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">return</span>&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">x</span>^<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">y</span><br style="max-width: 100%; box-sizing: border-box !important;">end<br style="max-width: 100%; box-sizing: border-box !important;">end<br style="max-width: 100%; box-sizing: border-box !important;"><br style="max-width: 100%; box-sizing: border-box !important;">expo (generic&nbsp;<span class="" style="max-width: 100%; background: rgba(0, 0, 0, 0); display: inline; width: 150px; text-decoration-style: solid; text-decoration-color: rgb(171, 178, 191); box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 52px;text-decoration-style: solid;text-decoration-color: rgb(198, 120, 221);">function</span>&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 26px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">with</span>&nbsp;1&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 39px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">method</span>)</span></code></pre></section><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">现在运行一下看看行不行:</span>&nbsp;</p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><br></p><section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="" mpa-preserve="t" style="max-width: 100%; color: rgb(63, 63, 63); font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; box-sizing: border-box !important;"><pre style="max-width: 100%; background: none; box-sizing: border-box !important;"><code class="" style="margin-right: 0.15em; margin-left: 0.15em; padding: 5.95px; max-width: 100%; border-radius: 4px; font-size: 0.85em; background: rgb(40, 44, 52); color: rgb(171, 178, 191); display: block; overflow-x: auto; white-space: nowrap; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(224, 108, 117); background: rgba(0, 0, 0, 0); display: inline; width: 45px; text-decoration-style: solid; text-decoration-color: rgb(224, 108, 117); box-sizing: border-box !important;">println</span>(expo(<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">2</span>,<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">5</span>))<br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(224, 108, 117); background: rgba(0, 0, 0, 0); display: inline; width: 26px; text-decoration-style: solid; text-decoration-color: rgb(224, 108, 117); box-sizing: border-box !important;">expo</span>(<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">2</span>,-<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">5</span>)<br style="max-width: 100%; box-sizing: border-box !important;"><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(224, 108, 117); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(224, 108, 117); box-sizing: border-box !important;">32</span><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(224, 108, 117); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(224, 108, 117); box-sizing: border-box !important;">0</span><span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 39px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">.03125</span></code></pre></section><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px;letter-spacing: 0.5px;">再来看看汇编代码。</span>&nbsp;</p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><br></p><section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="" mpa-preserve="t" style="max-width: 100%; color: rgb(63, 63, 63); font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; box-sizing: border-box !important;"><pre style="max-width: 100%; background: none; box-sizing: border-box !important;"><code class="" style="margin-right: 0.15em; margin-left: 0.15em; padding: 5.95px; max-width: 100%; border-radius: 4px; font-size: 0.85em; background: rgb(40, 44, 52); color: rgb(171, 178, 191); display: block; overflow-x: auto; white-space: nowrap; box-sizing: border-box !important;">@code_native expo(<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">2</span>,<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">5</span>)<br style="max-width: 100%; box-sizing: border-box !important;"><br style="max-width: 100%; box-sizing: border-box !important;">.text<br style="max-width: 100%; box-sizing: border-box !important;">;&nbsp;<span class="" style="max-width: 100%; background: rgba(0, 0, 0, 0); display: inline; width: 91px; text-decoration-style: solid; text-decoration-color: rgb(171, 178, 191); box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 53px;text-decoration-style: solid;text-decoration-color: rgb(198, 120, 221);">Function</span>&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 27px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">expo</span>&nbsp;</span>{<br style="max-width: 100%; box-sizing: border-box !important;">; Location: In[<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">8</span>]:<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">2</span><br style="max-width: 100%; box-sizing: border-box !important;">pushq %rbx<br style="max-width: 100%; box-sizing: border-box !important;">movq %rdi, %rbx<br style="max-width: 100%; box-sizing: border-box !important;">;&nbsp;<span class="" style="max-width: 100%; background: rgba(0, 0, 0, 0); display: inline; width: 65px; text-decoration-style: solid; text-decoration-color: rgb(171, 178, 191); box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 53px;text-decoration-style: solid;text-decoration-color: rgb(198, 120, 221);">Function</span>&nbsp;&gt;</span>; {<br style="max-width: 100%; box-sizing: border-box !important;">; Location: operators.jl:<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 19px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">286</span><br style="max-width: 100%; box-sizing: border-box !important;">;&nbsp;<span class="" style="max-width: 100%; background: rgba(0, 0, 0, 0); display: inline; width: 65px; text-decoration-style: solid; text-decoration-color: rgb(171, 178, 191); box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 53px;text-decoration-style: solid;text-decoration-color: rgb(198, 120, 221);">Function</span>&nbsp;&lt;</span>; {<br style="max-width: 100%; box-sizing: border-box !important;">; Location: int.jl:<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">49</span><br style="max-width: 100%; box-sizing: border-box !important;">testq %rdx, %rdx<br style="max-width: 100%; box-sizing: border-box !important;">;}}<br style="max-width: 100%; box-sizing: border-box !important;">jle L36<br style="max-width: 100%; box-sizing: border-box !important;">; Location: In[<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">8</span>]:<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">3</span><br style="max-width: 100%; box-sizing: border-box !important;">;&nbsp;<span class="" style="max-width: 100%; background: rgba(0, 0, 0, 0); display: inline; width: 65px; text-decoration-style: solid; text-decoration-color: rgb(171, 178, 191); box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 53px;text-decoration-style: solid;text-decoration-color: rgb(198, 120, 221);">Function</span>&nbsp;^</span>; {<br style="max-width: 100%; box-sizing: border-box !important;">; Location: intfuncs.jl:<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 19px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">220</span><br style="max-width: 100%; box-sizing: border-box !important;">movabsq $power_by_squaring, %rax<br style="max-width: 100%; box-sizing: border-box !important;">movq %rsi, %rdi<br style="max-width: 100%; box-sizing: border-box !important;">movq %rdx, %rsi<br style="max-width: 100%; box-sizing: border-box !important;">callq *%rax<br style="max-width: 100%; box-sizing: border-box !important;">;}<br style="max-width: 100%; box-sizing: border-box !important;">movq %rax, (%rbx)<br style="max-width: 100%; box-sizing: border-box !important;">movb $<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">2</span>, %dl<br style="max-width: 100%; box-sizing: border-box !important;">xorl %eax, %eax<br style="max-width: 100%; box-sizing: border-box !important;">popq %rbx<br style="max-width: 100%; box-sizing: border-box !important;">retq<br style="max-width: 100%; box-sizing: border-box !important;">; Location: In[<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">8</span>]:<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">5</span><br style="max-width: 100%; box-sizing: border-box !important;">;&nbsp;<span class="" style="max-width: 100%; background: rgba(0, 0, 0, 0); display: inline; width: 105px; text-decoration-style: solid; text-decoration-color: rgb(171, 178, 191); box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 53px;text-decoration-style: solid;text-decoration-color: rgb(198, 120, 221);">Function</span>&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 46px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">convert</span></span>; {<br style="max-width: 100%; box-sizing: border-box !important;">; Location: number.jl:<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">7</span><br style="max-width: 100%; box-sizing: border-box !important;">;&nbsp;<span class="" style="max-width: 100%; background: rgba(0, 0, 0, 0); display: inline; width: 85px; text-decoration-style: solid; text-decoration-color: rgb(171, 178, 191); box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 53px;text-decoration-style: solid;text-decoration-color: rgb(198, 120, 221);">Function</span>&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 27px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">Type</span></span>; {<br style="max-width: 100%; box-sizing: border-box !important;">; Location: float.jl:<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">60</span><br style="max-width: 100%; box-sizing: border-box !important;">L36:<br style="max-width: 100%; box-sizing: border-box !important;">vcvtsi2sdq %rsi, %xmm0, %xmm0<br style="max-width: 100%; box-sizing: border-box !important;">;}}<br style="max-width: 100%; box-sizing: border-box !important;">; Location: In[<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">8</span>]:<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">6</span><br style="max-width: 100%; box-sizing: border-box !important;">;&nbsp;<span class="" style="max-width: 100%; background: rgba(0, 0, 0, 0); display: inline; width: 65px; text-decoration-style: solid; text-decoration-color: rgb(171, 178, 191); box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 53px;text-decoration-style: solid;text-decoration-color: rgb(198, 120, 221);">Function</span>&nbsp;^</span>; {<br style="max-width: 100%; box-sizing: border-box !important;">; Location: math.jl:<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 19px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">780</span><br style="max-width: 100%; box-sizing: border-box !important;">;&nbsp;<span class="" style="max-width: 100%; background: rgba(0, 0, 0, 0); display: inline; width: 85px; text-decoration-style: solid; text-decoration-color: rgb(171, 178, 191); box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 53px;text-decoration-style: solid;text-decoration-color: rgb(198, 120, 221);">Function</span>&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 27px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">Type</span></span>; {<br style="max-width: 100%; box-sizing: border-box !important;">; Location: float.jl:<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">60</span><br style="max-width: 100%; box-sizing: border-box !important;">vcvtsi2sdq %rdx, %xmm1, %xmm1<br style="max-width: 100%; box-sizing: border-box !important;">movabsq $__pow, %rax<br style="max-width: 100%; box-sizing: border-box !important;">;}<br style="max-width: 100%; box-sizing: border-box !important;">callq *%rax<br style="max-width: 100%; box-sizing: border-box !important;">;}<br style="max-width: 100%; box-sizing: border-box !important;">vmovsd %xmm0, (%rbx)<br style="max-width: 100%; box-sizing: border-box !important;">movb $<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">1</span>, %dl<br style="max-width: 100%; box-sizing: border-box !important;">xorl %eax, %eax<br style="max-width: 100%; box-sizing: border-box !important;">; Location: In[<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">8</span>]:<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">3</span><br style="max-width: 100%; box-sizing: border-box !important;">popq %rbx<br style="max-width: 100%; box-sizing: border-box !important;">retq<br style="max-width: 100%; box-sizing: border-box !important;">nopw %cs:(%rax,%rax)<br style="max-width: 100%; box-sizing: border-box !important;">;}</code></pre></section><p style="margin-left: 8px;margin-right: 8px;"><span style="letter-spacing: 0.5px;font-size: 15px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;"><span style="letter-spacing: 0.5px;font-size: 15px;">这是一个非常直观的演示,说明了 Julia 通过使用类型推断获得了比其他脚本语言更高的性能。</span></p><p style="margin-left: 8px;margin-right: 8px;"><span style="letter-spacing: 0.5px;font-size: 15px;"><br></span></p><section style="border-width: 0px;border-style: initial;border-color: initial;clear: both;box-sizing: border-box;" class="tn-Powered-by-XIUMI"><section style="padding: 8px;border-left: 6px solid rgb(255, 202, 0);font-size: 112.5%;line-height: 1.4;font-family: inherit;font-weight: bold;text-decoration: inherit;color: rgb(10, 10, 10);border-top-color: rgb(255, 202, 0);border-right-color: rgb(255, 202, 0);border-bottom-color: rgb(255, 202, 0);box-sizing: border-box;" class="tn-Powered-by-XIUMI"><section class="tn-Powered-by-XIUMI">核心思想:多重分派 + 类型稳定性 =&gt; 速度 + 可读性<br></section></section></section><p><span style="letter-spacing: 0.5px;font-size: 15px;"><br></span></p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="letter-spacing: 0.5px;font-size: 15px;">类型稳定性是 Julia 区别于其他脚本语言的一个关键特性。事实上,Julia 的核心思想是这样的:</span></p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="letter-spacing: 0.5px;font-size: 15px;"><br></span></p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="color: rgb(255, 104, 39);"><strong><span style="letter-spacing: 0.5px;font-size: 15px;">多重分派允许一种语言将函数调用分派给类型稳定的函数。</span></strong></span></p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="letter-spacing: 0.5px;font-size: 15px;"><br></span></p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="letter-spacing: 0.5px;font-size: 15px;">这就是</span><span style="letter-spacing: 0.5px;font-size: 15px;color: rgb(255, 104, 39);"><strong> Julia 的核心思想</strong></span><span style="letter-spacing: 0.5px;font-size: 15px;">,现在让我们花点时间深入了解一下。如果函数内部具有类型稳定性(也就是说,函数内的任意函数调用也是类型稳定的),那么编译器就会知道每一步的变量类型,它就可以在编译函数时进行充分的优化,这样得到的代码基本上与 C 语言或 Fortran 相同。多重分派在这里可以起到作用,它意味着 “*” 可以是一个类型稳定的函数:对于不同的输入,它有不同的含义。但是,如果编译器在调用 “*” 之前能够知道 a 和 b 的类型,那么它就知道应该使用哪个 “*” 方法,这样它就知道 c=a*b 的输出类型是什么。这样它就可以将类型信息一路传下去,从而实现全面的优化。</span></p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="letter-spacing: 0.5px;font-size: 15px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;"><span style="letter-spacing: 0.5px;font-size: 15px;">我们从中可以学到一些东西。首先,为了实现这种级别的优化,必须具有类型稳定性。大多数语言为了让用户可以更轻松地编码,都没有在标准库中提供这种特性。其次,需要通过多重分派来专门化类型函数,让脚本语言语法 “看上去更显式” 一些。最后,需要一个健壮的类型系统。为了构建非类型稳定的乘方运算,我们需要使用转换函数。因此,要在保持脚本语言的语法和易用性的同时实现这种原始性能必须将语言设计成具有多重分派类型稳定性的语言,并提供一个健壮的类型系统。</span></p><p style="margin-left: 8px;margin-right: 8px;"><span style="letter-spacing: 0.5px;font-size: 15px;"><br></span></p><section style="border-width: 0px;border-style: initial;border-color: initial;clear: both;box-sizing: border-box;" class="tn-Powered-by-XIUMI"><section style="padding: 8px;border-left: 6px solid rgb(255, 202, 0);font-size: 112.5%;line-height: 1.4;font-family: inherit;font-weight: bold;text-decoration: inherit;color: rgb(10, 10, 10);border-top-color: rgb(255, 202, 0);border-right-color: rgb(255, 202, 0);border-bottom-color: rgb(255, 202, 0);box-sizing: border-box;" class="tn-Powered-by-XIUMI"><section class="tn-Powered-by-XIUMI">Julia 基准测试<br></section></section></section><p><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">Julia 官网提供的基准测试只是针对编程语言组件的执行速度,并没有说是在测试最快的实现,所以这里存在一个很大的误解。R 语言程序员一边看着使用 R 语言实现的 Fibonacci 函数,一边说:“这是一段很糟糕的代码,不应该在 R 语言中使用递归,因为递归很慢”。但实际上,Fibonacci 函数是用来测试递归的,而不是用来测试语言的执行速度的。</span></p><p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">Julia 使用了类型稳定函数的多重分派机制,因此,即使是早期版本的 Julia 也可以优化得像 C 语言或 Fortran 那样。非常明显,几乎在所有情况下,Julia 都非常接近 C 语言。当然,也有与 C 语言不一样的地方,我们可以来看看这些细节。首先是在计算 Fibonacci 数列时 C 语言比 Julia 快 2.11 倍,这是因为这是针对递归的测试,而 Julia 并没有完全为递归进行过优化。Julia 其实也可以加入这种优化(尾递归优化),只是出于某些原因他们才没有这么做,最主要是因为:可以使用尾递归的地方也可以使用循环,而循环是一种更加健壮的优化,所以他们建议使用循环来代替脆弱的尾递归。</span></p><p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">Julia 表现不太好的地方还有 rand_mat_stat 和 parse_int 测试。这主要是因为边界检查导致的。在大多数脚本语言中,如果你试图访问超出数组边界的元素就会出错,Julia 默认情况下也会这么做。</span>&nbsp;</p><p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><br></p><section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="" mpa-preserve="t" style="max-width: 100%; color: rgb(63, 63, 63); font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; box-sizing: border-box !important;"><pre style="max-width: 100%; background: none; box-sizing: border-box !important;"><code class="" style="margin-right: 0.15em; margin-left: 0.15em; padding: 5.95px; max-width: 100%; border-radius: 4px; font-size: 0.85em; background: rgb(40, 44, 52); color: rgb(171, 178, 191); display: block; overflow-x: auto; white-space: nowrap; box-sizing: border-box !important;">function test1()<br style="max-width: 100%; box-sizing: border-box !important;">a = zeros(3)<br style="max-width: 100%; box-sizing: border-box !important;">for i=1:4<br style="max-width: 100%; box-sizing: border-box !important;">a = i<br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 19px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">end</span><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 19px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">end</span><br style="max-width: 100%; box-sizing: border-box !important;">test1()<br style="max-width: 100%; box-sizing: border-box !important;"><br style="max-width: 100%; box-sizing: border-box !important;">BoundsError: attempt&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">to</span>&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 39px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">access</span>&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">3</span>-<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 46px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">element</span>&nbsp;<span class="" style="max-width: 100%; color: rgb(230, 192, 123); background: rgba(0, 0, 0, 0); display: inline; width: 33px; text-decoration-style: solid; text-decoration-color: rgb(230, 192, 123); box-sizing: border-box !important;">Array</span>{Float64,<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">1</span>}&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">at</span>&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 33px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">index</span>&nbsp;[<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">4</span>]<br style="max-width: 100%; box-sizing: border-box !important;"><br style="max-width: 100%; box-sizing: border-box !important;">Stacktrace:<br style="max-width: 100%; box-sizing: border-box !important;">[<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">1</span>] setindex!&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">at</span>&nbsp;./array.jl:<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 19px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">769</span>&nbsp;<br style="max-width: 100%; box-sizing: border-box !important;">[<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">2</span>] test1()&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">at</span>&nbsp;./<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">In</span>[<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">11</span>]:<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">4</span><br style="max-width: 100%; box-sizing: border-box !important;">[<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">3</span>] top-<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 33px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">level</span>&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 33px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">scope</span>&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">at</span>&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">In</span>[<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">11</span>]:<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">7</span></code></pre></section><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">不过,你可以使用 @inbounds 宏来禁用这个功能:</span>&nbsp;</p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><br></p><section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="" mpa-preserve="t" style="max-width: 100%; color: rgb(63, 63, 63); font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; box-sizing: border-box !important;"><pre style="max-width: 100%; background: none; box-sizing: border-box !important;"><code class="" style="margin-right: 0.15em; margin-left: 0.15em; padding: 5.95px; max-width: 100%; border-radius: 4px; font-size: 0.85em; background: rgb(40, 44, 52); color: rgb(171, 178, 191); display: block; overflow-x: auto; white-space: nowrap; box-sizing: border-box !important;"><span class="" style="max-width: 100%; background: rgba(0, 0, 0, 0); display: inline; width: 150px; text-decoration-style: solid; text-decoration-color: rgb(171, 178, 191); box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 52px;text-decoration-style: solid;text-decoration-color: rgb(198, 120, 221);">function</span>&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 33px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">test2</span>()<br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 7px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">a</span>&nbsp;=&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 33px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">zeros</span>(<span class="" style="max-width: 100%;background: rgba(0, 0, 0, 0);display: inline;width: 7px;text-decoration-style: solid;text-decoration-color: rgb(171, 178, 191);">3</span>)<br style="max-width: 100%; box-sizing: border-box !important;">@<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 52px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">inbounds</span>&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 19px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">for</span>&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 7px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">i</span>=1:4<br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 7px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">a</span>[<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 6px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">i</span>] =&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 6px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">i</span><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 19px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">end</span><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 19px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">end</span><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 33px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">test2</span>()</span></code></pre></section><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">这样你就获得了与 C 语言或 Fortran 一样的不安全行为和执行速度。这是 Julia 的另一个有趣的特性:默认情况下是一个安全的脚本语言特性,在必要的时候禁用这个功能,以便获得性能提升。</span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><section style="border-width: 0px;border-style: initial;border-color: initial;clear: both;box-sizing: border-box;" class="tn-Powered-by-XIUMI"><section style="padding: 8px;border-left: 6px solid rgb(255, 202, 0);font-size: 112.5%;line-height: 1.4;font-family: inherit;font-weight: bold;text-decoration: inherit;color: rgb(10, 10, 10);border-top-color: rgb(255, 202, 0);border-right-color: rgb(255, 202, 0);border-bottom-color: rgb(255, 202, 0);box-sizing: border-box;" class="tn-Powered-by-XIUMI"><section class="tn-Powered-by-XIUMI">严格类型<br></section></section></section><p><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">除了类型稳定性,你还需要严格类型。在 Python 中,你可以将任何东西放入数组中。而在 Julia 中,你只能将类型 T 放入 Vector {T} 中。Julia 提供了各种非严格的类型,例如 Any。如果有必要,可以创建 Vector {Any},例如:</span>&nbsp;</p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><br></p><section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="" mpa-preserve="t" style="max-width: 100%; color: rgb(63, 63, 63); font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; box-sizing: border-box !important;"><pre style="max-width: 100%; background: none; box-sizing: border-box !important;"><code class="" style="margin-right: 0.15em; margin-left: 0.15em; padding: 5.95px; max-width: 100%; border-radius: 4px; font-size: 0.85em; background: rgb(40, 44, 52); color: rgb(171, 178, 191); display: block; overflow-x: auto; white-space: nowrap; box-sizing: border-box !important;">a = Vector{Any}(<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 33px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">undef</span>,<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">3</span>)<br style="max-width: 100%; box-sizing: border-box !important;">a[<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">1</span>] =&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 20px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">1.0</span><br style="max-width: 100%; box-sizing: border-box !important;">a[<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">2</span>] =&nbsp;<span class="" style="max-width: 100%; color: rgb(152, 195, 121); background: rgba(0, 0, 0, 0); display: inline; width: 33px; text-decoration-style: solid; text-decoration-color: rgb(152, 195, 121); box-sizing: border-box !important;">"hi!"</span><br style="max-width: 100%; box-sizing: border-box !important;">a[<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">3</span>] =&nbsp;<span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 59px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">:Symbolic</span><br style="max-width: 100%; box-sizing: border-box !important;">a<br style="max-width: 100%; box-sizing: border-box !important;"><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">3</span>-element Array{Any,<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">1</span>}:<br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 20px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">1.0</span>&nbsp;<br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(152, 195, 121); background: rgba(0, 0, 0, 0); display: inline; width: 33px; text-decoration-style: solid; text-decoration-color: rgb(152, 195, 121); box-sizing: border-box !important;">"hi!"</span>&nbsp;<br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 59px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">:Symbolic</span></code></pre></section><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;">Union 是另一个不那么极端的抽象类型,例如:</span>&nbsp;</p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><br></p><section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="" mpa-preserve="t" style="max-width: 100%; color: rgb(63, 63, 63); font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; box-sizing: border-box !important;"><pre style="max-width: 100%; background: none; box-sizing: border-box !important;"><code class="" style="margin-right: 0.15em; margin-left: 0.15em; padding: 5.95px; max-width: 100%; border-radius: 4px; font-size: 0.85em; background: rgb(40, 44, 52); color: rgb(171, 178, 191); display: block; overflow-x: auto; white-space: nowrap; box-sizing: border-box !important;">a = Vector{Union{Float64,Int}}(undef,<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">3</span>)<br style="max-width: 100%; box-sizing: border-box !important;">a[<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">1</span>] =&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 20px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">1.0</span><br style="max-width: 100%; box-sizing: border-box !important;">a[<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">2</span>] =&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">3</span><br style="max-width: 100%; box-sizing: border-box !important;">a[<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">3</span>] =&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">1</span>/<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">4</span><br style="max-width: 100%; box-sizing: border-box !important;">a<br style="max-width: 100%; box-sizing: border-box !important;"><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">3</span>-element&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 33px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">Array</span>{Union{Float64, Int64},<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">1</span>}:<br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 20px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">1.0</span>&nbsp;<br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">3</span>&nbsp;<br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 27px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">0.25</span></code></pre></section><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">这个 Union 只接受浮点数和整数。不过,它仍然是一个抽象类型。接受抽象类型作为参数的函数无法知道元素的类型(在这个例子中,元素要么是浮点数,要么是整数),这个时候,多重分派优化在这里起不到作用,所以 Julia 此时的性能就不如其他脚本语言。</span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">所以我们可以得出一个性能原则:<strong>尽可能使用严格类型</strong>。使用严格类型还有其他好处:严格类型的 Vector {Float64} 实际上与 C 语言或 Fortran 是字节兼容的,所以不经过转换就可以直接用在 C 语言或 Fortran 程序中。</span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><section style="border-width: 0px;border-style: initial;border-color: initial;clear: both;box-sizing: border-box;" class="tn-Powered-by-XIUMI"><section style="padding: 8px;border-left: 6px solid rgb(255, 202, 0);font-size: 112.5%;line-height: 1.4;font-family: inherit;font-weight: bold;text-decoration: inherit;color: rgb(10, 10, 10);border-top-color: rgb(255, 202, 0);border-right-color: rgb(255, 202, 0);border-bottom-color: rgb(255, 202, 0);box-sizing: border-box;" class="tn-Powered-by-XIUMI"><section class="tn-Powered-by-XIUMI">不免费的午餐<br></section></section></section><p><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px;letter-spacing: 0.5px;">很明显,Julia 为了在保持脚本语言特征的同时实现性能目标,做出了非常明智的设计决策。但是,它也为此付出了一些代价。接下来,我将展示 Julia 的一些奇特的东西及其相应的工具。</span></p><p style="margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><section style="border-width: 0px;border-style: initial;border-color: initial;clear: both;box-sizing: border-box;" class="tn-Powered-by-XIUMI"><section style="padding: 8px;border-left: 6px solid rgb(255, 202, 0);font-size: 112.5%;line-height: 1.4;font-family: inherit;font-weight: bold;text-decoration: inherit;color: rgb(10, 10, 10);border-top-color: rgb(255, 202, 0);border-right-color: rgb(255, 202, 0);border-bottom-color: rgb(255, 202, 0);box-sizing: border-box;" class="tn-Powered-by-XIUMI"><section class="tn-Powered-by-XIUMI">性能是可选的<br></section></section></section><p><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">之前已经说明了 Julia 提供了多种方法来提升性能(比如 @inbounds),但我们不一定要使用它们。你也可以编写类型不稳定的函数,虽然与 MATLAB、R 语言、Python 一样慢,但你绝对可以这么做。在对性能要求没有那么高的地方,可以将其作为一个可选项。</span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><section style="border-width: 0px;border-style: initial;border-color: initial;clear: both;box-sizing: border-box;" class="tn-Powered-by-XIUMI"><section style="padding: 8px;border-left: 6px solid rgb(255, 202, 0);font-size: 112.5%;line-height: 1.4;font-family: inherit;font-weight: bold;text-decoration: inherit;color: rgb(10, 10, 10);border-top-color: rgb(255, 202, 0);border-right-color: rgb(255, 202, 0);border-bottom-color: rgb(255, 202, 0);box-sizing: border-box;" class="tn-Powered-by-XIUMI"><section class="tn-Powered-by-XIUMI">检查类型稳定性<br></section></section></section><p><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">由于类型稳定性非常重要,Julia 为我们提供了一些工具,用来检查一个函数是不是类型稳定的,其中最重要的是 @code_warntype 宏。让我们用它来检查一个类型稳定的函数:</span>&nbsp;</p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><br></p><section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="" mpa-preserve="t" style="max-width: 100%; color: rgb(63, 63, 63); font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; box-sizing: border-box !important;"><pre style="max-width: 100%; background: none; box-sizing: border-box !important;"><code class="" style="margin-right: 0.15em; margin-left: 0.15em; padding: 5.95px; max-width: 100%; border-radius: 4px; font-size: 0.85em; background: rgb(40, 44, 52); color: rgb(171, 178, 191); display: block; overflow-x: auto; white-space: nowrap; box-sizing: border-box !important;">@code_warntype&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">2</span>^<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">5</span><br style="max-width: 100%; box-sizing: border-box !important;"><br style="max-width: 100%; box-sizing: border-box !important;">Body::Int64<br style="max-width: 100%; box-sizing: border-box !important;">│<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 20px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">220</span>&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">1</span>&nbsp;─ %<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">1</span>&nbsp;= invoke Base.power_by_squaring(<span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 20px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">_2:</span><span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 39px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">:Int64</span>,&nbsp;<span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 19px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">_3:</span><span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 39px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">:Int64</span>)<span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">:</span><span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 39px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">:Int64</span><br style="max-width: 100%; box-sizing: border-box !important;">│ └──&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 39px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">return</span>&nbsp;%<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">1</span></code></pre></section><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">请注意,它将函数中所有变量都显示为严格类型。那么 expo 会是怎样的?</span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;">&nbsp;</p><section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="" mpa-preserve="t" style="max-width: 100%; color: rgb(63, 63, 63); font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; box-sizing: border-box !important;"><pre style="max-width: 100%; background: none; box-sizing: border-box !important;"><code class="" style="margin-right: 0.15em; margin-left: 0.15em; padding: 5.95px; max-width: 100%; border-radius: 4px; font-size: 0.85em; background: rgb(40, 44, 52); color: rgb(171, 178, 191); display: block; overflow-x: auto; white-space: nowrap; box-sizing: border-box !important;">@code_warntype expo(<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">2</span>,<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">5</span>)<br style="max-width: 100%; box-sizing: border-box !important;"><br style="max-width: 100%; box-sizing: border-box !important;">Body::Union{Float64, Int64}<br style="max-width: 100%; box-sizing: border-box !important;">│╻╷ &gt;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">2</span>&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">1</span>&nbsp;─ %<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">1</span>&nbsp;= (Base.slt_int)(<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">0</span>, y)<span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">:</span><span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 33px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">:Bool</span><br style="max-width: 100%; box-sizing: border-box !important;">│ └── goto&nbsp;<span class="" style="max-width: 100%; color: rgb(92, 99, 112); background: rgba(0, 0, 0, 0); display: inline; width: 78px; text-decoration-style: solid; text-decoration-color: rgb(92, 99, 112); font-style: italic; box-sizing: border-box !important;">#3 if not %1</span><br style="max-width: 100%; box-sizing: border-box !important;">│&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">3</span>&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">2</span>&nbsp;─ %<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">3</span>&nbsp;= π (x, Int64)<br style="max-width: 100%; box-sizing: border-box !important;">│╻ ^ │ %<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">4</span>&nbsp;= invoke Base.power_by_squaring(%<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">3</span><span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">:</span><span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 39px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">:Int64</span>,&nbsp;<span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 20px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">_3:</span><span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 39px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">:Int64</span>)<span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">:</span><span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 39px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">:Int64</span><br style="max-width: 100%; box-sizing: border-box !important;">│ └──&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 39px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">return</span>&nbsp;%<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">4</span><br style="max-width: 100%; box-sizing: border-box !important;">│&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">5</span>&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">3</span>&nbsp;─ %<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">6</span>&nbsp;= π (x, Int64)<br style="max-width: 100%; box-sizing: border-box !important;">││╻ Type │ %<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">7</span>&nbsp;= (Base.sitofp)(Float64, %<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">6</span>)<span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">:</span><span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 53px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">:Float64</span><br style="max-width: 100%; box-sizing: border-box !important;">│&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">6</span>&nbsp;│ %<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">8</span>&nbsp;= π (%<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">7</span>, Float64)<br style="max-width: 100%; box-sizing: border-box !important;">│╻ ^ │ %<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">9</span>&nbsp;= (Base.sitofp)(Float64, y)<span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">:</span><span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 53px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">:Float64</span><br style="max-width: 100%; box-sizing: border-box !important;">││ │ %<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">10</span>&nbsp;= $(Expr(<span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 79px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">:foreigncall</span>,&nbsp;<span class="" style="max-width: 100%; color: rgb(152, 195, 121); background: rgba(0, 0, 0, 0); display: inline; width: 91px; text-decoration-style: solid; text-decoration-color: rgb(152, 195, 121); box-sizing: border-box !important;">"llvm.pow.f64"</span>, Float64, svec(Float64, Float64),&nbsp;<span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">:</span>(<span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 59px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">:llvmcall</span>),&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">2</span>,&nbsp;<span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">:</span>(%<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">8</span>),&nbsp;<span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">:</span>(%<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">9</span>),&nbsp;<span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">:</span>(%<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">9</span>),&nbsp;<span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">:</span>(%<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">8</span>)))<span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">:</span><span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 53px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">:Float64</span><br style="max-width: 100%; box-sizing: border-box !important;">│ └──&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 39px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">return</span>&nbsp;%<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">10</span></code></pre></section><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">请注意,可能的返回值是%4 和%10,它们是不同的类型,因此返回类型被推断为 Union {Float64,Int64}。为了准确地追踪这种不稳定性发生的位置,我们可以使用 Traceur.jl:</span>&nbsp;</p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><br></p><section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="" mpa-preserve="t" style="max-width: 100%; color: rgb(63, 63, 63); font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; box-sizing: border-box !important;"><pre style="max-width: 100%; background: none; box-sizing: border-box !important;"><code class="" style="margin-right: 0.15em; margin-left: 0.15em; padding: 5.95px; max-width: 100%; border-radius: 4px; font-size: 0.85em; background: rgb(40, 44, 52); color: rgb(171, 178, 191); display: block; overflow-x: auto; white-space: nowrap; box-sizing: border-box !important;">using Traceur<br style="max-width: 100%; box-sizing: border-box !important;">@trace expo(<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">2</span>,<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">5</span>)<br style="max-width: 100%; box-sizing: border-box !important;"><br style="max-width: 100%; box-sizing: border-box !important;">┌ Warnin<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">g:</span>&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">x</span>&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">is</span>&nbsp;assigned&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">as</span>&nbsp;Int64<br style="max-width: 100%; box-sizing: border-box !important;">└ @ In[<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">8</span>]:<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">2</span><br style="max-width: 100%; box-sizing: border-box !important;">┌ Warnin<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">g:</span>&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">x</span>&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">is</span>&nbsp;assigned&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">as</span>&nbsp;Float64<br style="max-width: 100%; box-sizing: border-box !important;">└ @ In[<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">8</span>]:<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">5</span><br style="max-width: 100%; box-sizing: border-box !important;">┌ Warnin<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">g:</span>&nbsp;expo returns Union{Float64, Int64}<br style="max-width: 100%; box-sizing: border-box !important;">└ @ In[<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">8</span>]:<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">2</span><br style="max-width: 100%; box-sizing: border-box !important;"><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">32</span></code></pre></section><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px;letter-spacing: 0.5px;">在第 2 行,x 被分配了一个 Int,而在第 5 行又被分配了一个 Float64,因此它被推断为 Union {Float64, Int64}。第 5 行是我们放置显式转换调用的地方,这样我们就确定了问题所在的位置。</span></p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><section style="border-width: 0px;border-style: initial;border-color: initial;clear: both;box-sizing: border-box;" class="tn-Powered-by-XIUMI"><section style="padding: 8px;border-left: 6px solid rgb(255, 202, 0);font-size: 112.5%;line-height: 1.4;font-family: inherit;font-weight: bold;text-decoration: inherit;color: rgb(10, 10, 10);border-top-color: rgb(255, 202, 0);border-right-color: rgb(255, 202, 0);border-bottom-color: rgb(255, 202, 0);box-sizing: border-box;" class="tn-Powered-by-XIUMI"><section class="tn-Powered-by-XIUMI">处理必要的类型不稳定性<br></section></section></section><p><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px;letter-spacing: 0.5px;">首先,我已经证明了某些在 Julia 会出错的函数在其他脚本语言中却可以 “读懂你的想法”。在很多情况下,你会发现你可以从一开始就使用不同的类型,以此来实现类型稳定性(为什么不直接使用 2.0^-5?)。但是,在某些情况下,你找不到合适的类型。这个问题可以通过转换来解决,但这样会失去类型稳定性。你必须重新考虑你的设计,并巧妙地使用多重分派。</span></p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px;letter-spacing: 0.5px;">假设我们有一个 Vector {Union {Float64,Int}} 类型的 a,并且可能遇到必须使用 a 的情况,需要在 a 的每个元素上执行大量操作。在这种情况下,知道给定元素的类型将带来性能的大幅提升,但由于类型位于 Vector {Union {Float64,Int}} 中,因此无法在下面这样的函数中识别出类型:</span>&nbsp;</p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><br></p><section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="" mpa-preserve="t" style="max-width: 100%; color: rgb(63, 63, 63); font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; box-sizing: border-box !important;"><pre style="max-width: 100%; background: none; box-sizing: border-box !important;"><code class="" style="margin-right: 0.15em; margin-left: 0.15em; padding: 5.95px; max-width: 100%; border-radius: 4px; font-size: 0.85em; background: rgb(40, 44, 52); color: rgb(171, 178, 191); display: block; overflow-x: auto; white-space: nowrap; box-sizing: border-box !important;"><span class="" style="max-width: 100%; background: rgba(0, 0, 0, 0); display: inline; width: 124px; text-decoration-style: solid; text-decoration-color: rgb(171, 178, 191); box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 52px;text-decoration-style: solid;text-decoration-color: rgb(198, 120, 221);">function</span>&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 19px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">foo</span><span class="" style="max-width: 100%;background: rgba(0, 0, 0, 0);display: inline;width: 46px;text-decoration-style: solid;text-decoration-color: rgb(171, 178, 191);">(array)</span></span><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 20px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">for</span>&nbsp;i in eachindex(array)<br style="max-width: 100%; box-sizing: border-box !important;">val = array<br style="max-width: 100%; box-sizing: border-box !important;">#&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">do</span>&nbsp;algorithm&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">X</span>&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">on</span>&nbsp;val<br style="max-width: 100%; box-sizing: border-box !important;">end<br style="max-width: 100%; box-sizing: border-box !important;">end<br style="max-width: 100%; box-sizing: border-box !important;"><br style="max-width: 100%; box-sizing: border-box !important;">foo (generic&nbsp;<span class="" style="max-width: 100%; background: rgba(0, 0, 0, 0); display: inline; width: 151px; text-decoration-style: solid; text-decoration-color: rgb(171, 178, 191); box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 53px;text-decoration-style: solid;text-decoration-color: rgb(198, 120, 221);">function</span>&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 27px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">with</span>&nbsp;1&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 39px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">method</span>)</span></code></pre></section><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">不过,我们可以通过多重分派来解决这个问题。我们可以在元素上使用分派:</span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;">&nbsp;</p><section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="" mpa-preserve="t" style="max-width: 100%; color: rgb(63, 63, 63); font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; box-sizing: border-box !important;"><pre style="max-width: 100%; background: none; box-sizing: border-box !important;"><code class="" style="margin-right: 0.15em; margin-left: 0.15em; padding: 5.95px; max-width: 100%; border-radius: 4px; font-size: 0.85em; background: rgb(40, 44, 52); color: rgb(171, 178, 191); display: block; overflow-x: auto; white-space: nowrap; box-sizing: border-box !important;"><span class="" style="max-width: 100%; background: rgba(0, 0, 0, 0); display: inline; width: 274px; text-decoration-style: solid; text-decoration-color: rgb(171, 178, 191); box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 52px;text-decoration-style: solid;text-decoration-color: rgb(198, 120, 221);">function</span>&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 59px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">inner_foo</span>(<span class="" style="max-width: 100%;background: rgba(0, 0, 0, 0);display: inline;width: 19px;text-decoration-style: solid;text-decoration-color: rgb(171, 178, 191);">val</span>)<br style="max-width: 100%; box-sizing: border-box !important;">#&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 13px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">Do</span>&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 59px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">algorithm</span>&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 7px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">X</span>&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 13px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">on</span>&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 20px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">val</span><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 19px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">end</span><br style="max-width: 100%; box-sizing: border-box !important;"><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 59px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">inner_foo</span>&nbsp;(<span class="" style="max-width: 100%;background: rgba(0, 0, 0, 0);display: inline;width: 197px;text-decoration-style: solid;text-decoration-color: rgb(171, 178, 191);">generic&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 52px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">function</span>&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 26px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">with</span>&nbsp;1 method</span>)</span></code></pre></section><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">然后将 foo 定义为:</span>&nbsp;</p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><br></p><section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="" mpa-preserve="t" style="max-width: 100%; color: rgb(63, 63, 63); font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; box-sizing: border-box !important;"><pre style="max-width: 100%; background: none; box-sizing: border-box !important;"><code class="" style="margin-right: 0.15em; margin-left: 0.15em; padding: 5.95px; max-width: 100%; border-radius: 4px; font-size: 0.85em; background: rgb(40, 44, 52); color: rgb(171, 178, 191); display: block; overflow-x: auto; white-space: nowrap; box-sizing: border-box !important;"><span class="" style="max-width: 100%; background: rgba(0, 0, 0, 0); display: inline; width: 241px; text-decoration-style: solid; text-decoration-color: rgb(171, 178, 191); box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 52px;text-decoration-style: solid;text-decoration-color: rgb(198, 120, 221);">function</span>&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 26px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">foo2</span>(<span class="" style="max-width: 100%;background: rgba(0, 0, 0, 0);display: inline;width: 79px;text-decoration-style: solid;text-decoration-color: rgb(171, 178, 191);">array::<span class="" style="max-width: 100%; color: rgb(230, 192, 123); background: rgba(0, 0, 0, 0); display: inline; width: 33px; text-decoration-style: solid; text-decoration-color: rgb(230, 192, 123); box-sizing: border-box !important;">Array</span></span>)<br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 20px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">for</span>&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 7px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">i</span>&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 13px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">in</span>&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 59px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">eachindex</span>(<span class="" style="max-width: 100%;background: rgba(0, 0, 0, 0);display: inline;width: 33px;text-decoration-style: solid;text-decoration-color: rgb(171, 178, 191);">array</span>)<br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 59px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">inner_foo</span>(<span class="" style="max-width: 100%;background: rgba(0, 0, 0, 0);display: inline;width: 52px;text-decoration-style: solid;text-decoration-color: rgb(171, 178, 191);">array</span>)<br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 20px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">end</span><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 19px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">end</span><br style="max-width: 100%; box-sizing: border-box !important;"><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 26px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">foo2</span>&nbsp;(<span class="" style="max-width: 100%;background: rgba(0, 0, 0, 0);display: inline;width: 197px;text-decoration-style: solid;text-decoration-color: rgb(171, 178, 191);">generic&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 52px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">function</span>&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 26px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">with</span>&nbsp;1 method</span>)</span></code></pre></section><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">因为需要为分派检查类型,所以 inner_foo 函数是严格类型化的。因此,如果 inner_foo 是类型稳定的,那么就可以通过专门化 inner_foo 来提高性能。这就导致了一个通用的设计原则:在处理奇怪或非严格的类型时,可以使用一个外部函数来处理逻辑类型,同时使用一个内部函数来处理计算任务,实现最佳的性能,同时仍然具备脚本语言的通用能力。</span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><section style="border-width: 0px;border-style: initial;border-color: initial;clear: both;box-sizing: border-box;" class="tn-Powered-by-XIUMI"><section style="padding: 8px;border-left: 6px solid rgb(255, 202, 0);font-size: 112.5%;line-height: 1.4;font-family: inherit;font-weight: bold;text-decoration: inherit;color: rgb(10, 10, 10);border-top-color: rgb(255, 202, 0);border-right-color: rgb(255, 202, 0);border-bottom-color: rgb(255, 202, 0);box-sizing: border-box;" class="tn-Powered-by-XIUMI"><section class="tn-Powered-by-XIUMI">REPL 的全局作用域性能很糟糕<br></section></section></section><p><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><span style="font-size: 15px;letter-spacing: 0.5px;">Julia 全局作用域的性能很糟糕。官方的性能指南建议不要使用全局作用域。然而,新手可能会意识不到 REPL 其实就是全局作用域。为什么?首先,Julia 是有嵌套作用域的。例如,如果函数内部有函数,那么内部函数就可以访问外部函数的所有变量。</span>&nbsp;</p><p style="line-height: 1.75em;margin-left: 8px;margin-right: 8px;"><br></p><section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="" mpa-preserve="t" style="max-width: 100%; color: rgb(63, 63, 63); font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; box-sizing: border-box !important;"><pre style="max-width: 100%; background: none; box-sizing: border-box !important;"><code class="" style="margin-right: 0.15em; margin-left: 0.15em; padding: 5.95px; max-width: 100%; border-radius: 4px; font-size: 0.85em; background: rgb(40, 44, 52); color: rgb(171, 178, 191); display: block; overflow-x: auto; white-space: nowrap; box-sizing: border-box !important;"><span class="" style="max-width: 100%; background: rgba(0, 0, 0, 0); display: inline; width: 241px; text-decoration-style: solid; text-decoration-color: rgb(171, 178, 191); box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 52px;text-decoration-style: solid;text-decoration-color: rgb(198, 120, 221);">function</span>&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 26px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">test</span>(<span class="" style="max-width: 100%;background: rgba(0, 0, 0, 0);display: inline;width: 7px;text-decoration-style: solid;text-decoration-color: rgb(171, 178, 191);">x</span>)<br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 7px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">y</span>&nbsp;=&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 7px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">x</span>+2<br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%;background: rgba(0, 0, 0, 0);display: inline;width: 242px;text-decoration-style: solid;text-decoration-color: rgb(171, 178, 191);"><span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 52px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">function</span>&nbsp;<span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 33px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">test2</span>()<br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">y</span>+3<br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 19px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">end</span><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 33px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">test2</span>()<br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 19px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">end</span><br style="max-width: 100%; box-sizing: border-box !important;"><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 26px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">test</span>&nbsp;(<span class="" style="max-width: 100%; background: rgba(0, 0, 0, 0); display: inline; width: 197px; text-decoration-style: solid; text-decoration-color: rgb(171, 178, 191); box-sizing: border-box !important;">generic&nbsp;<span class="" style="max-width: 100%;color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 52px;text-decoration-style: solid;text-decoration-color: rgb(198, 120, 221);">function</span>&nbsp;<span class="" style="max-width: 100%;color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 26px;text-decoration-style: solid;text-decoration-color: rgb(198, 120, 221);">with</span>&nbsp;1 method</span>)</span></span></code></pre></section><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">在 test2 中,y 是已知的,因为它是在 test 中定义的。如果 y 是类型稳定的,那么所有这些工作就可以带来性能的提升,因为 test2 可以假设 y 是一个整数。现在让我们来看一下在全局作用域里会发生什么:</span>&nbsp;</p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><br></p><section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="" mpa-preserve="t" style="max-width: 100%; color: rgb(63, 63, 63); font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; box-sizing: border-box !important;"><pre style="max-width: 100%; background: none; box-sizing: border-box !important;"><code class="" style="margin-right: 0.15em; margin-left: 0.15em; padding: 5.95px; max-width: 100%; border-radius: 4px; font-size: 0.85em; background: rgb(40, 44, 52); color: rgb(171, 178, 191); display: block; overflow-x: auto; white-space: nowrap; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">a</span>&nbsp;=&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">3</span><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; background: rgba(0, 0, 0, 0); display: inline; width: 117px; text-decoration-style: solid; text-decoration-color: rgb(171, 178, 191); box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 52px;text-decoration-style: solid;text-decoration-color: rgb(198, 120, 221);">function</span>&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 46px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">badidea</span><span class="" style="max-width: 100%;background: rgba(0, 0, 0, 0);display: inline;width: 13px;text-decoration-style: solid;text-decoration-color: rgb(171, 178, 191);">()</span></span><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">a</span>&nbsp;+&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">2</span><br style="max-width: 100%; box-sizing: border-box !important;">end<br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">a</span>&nbsp;=&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 19px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">3.0</span><br style="max-width: 100%; box-sizing: border-box !important;"><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 19px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">3.0</span></code></pre></section><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">因为没有使用分派来专门化 badidea,并且可以随时更改 a 的类型,因此 badidea 在编译时无法进行优化,因为在编译期间 a 的类型是未知的。但是,Julia 允许我们声明常量:</span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;">&nbsp;</p><section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="" mpa-preserve="t" style="max-width: 100%; color: rgb(63, 63, 63); font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; box-sizing: border-box !important;"><pre style="max-width: 100%; background: none; box-sizing: border-box !important;"><code class="" style="margin-right: 0.15em; margin-left: 0.15em; padding: 5.95px; max-width: 100%; border-radius: 4px; font-size: 0.85em; background: rgb(40, 44, 52); color: rgb(171, 178, 191); display: block; overflow-x: auto; white-space: nowrap; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 33px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">const</span>&nbsp;a_cons =&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">3</span><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; background: rgba(0, 0, 0, 0); display: inline; width: 261px; text-decoration-style: solid; text-decoration-color: rgb(171, 178, 191); box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(198, 120, 221);background: rgba(0, 0, 0, 0);display: inline;width: 52px;text-decoration-style: solid;text-decoration-color: rgb(198, 120, 221);">function</span>&nbsp;<span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 46px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">badidea</span>()<br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 39px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">a_cons</span>&nbsp;+ 2<br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 19px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">end</span><br style="max-width: 100%; box-sizing: border-box !important;"><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%;color: rgb(97, 174, 238);background: rgba(0, 0, 0, 0);display: inline;width: 45px;text-decoration-style: solid;text-decoration-color: rgb(97, 174, 238);">badidea</span>&nbsp;(<span class="" style="max-width: 100%;background: rgba(0, 0, 0, 0);display: inline;width: 196px;text-decoration-style: solid;text-decoration-color: rgb(171, 178, 191);">generic&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 53px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">function</span>&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 26px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">with</span>&nbsp;1 method</span>)</span></code></pre></section><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">请注意,函数将使用常量的值来进行专门化,因此它们在设置后应该保持不变。</span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">在进行基准测试时会出现这种情况。新手会像下面这样对 Julia 进行基准测试:</span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">&nbsp;&nbsp;</span></p><section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="" mpa-preserve="t" style="max-width: 100%; color: rgb(63, 63, 63); font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; box-sizing: border-box !important;"><pre style="max-width: 100%; background: none; box-sizing: border-box !important;"><code class="" style="margin-right: 0.15em; margin-left: 0.15em; padding: 5.95px; max-width: 100%; border-radius: 4px; font-size: 0.85em; background: rgb(40, 44, 52); color: rgb(171, 178, 191); display: block; overflow-x: auto; white-space: nowrap; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">a</span>&nbsp;=&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 19px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">3.0</span><br style="max-width: 100%; box-sizing: border-box !important;">@time&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 20px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">for</span>&nbsp;i =&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">1</span>:<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">4</span><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 39px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">global</span>&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">a</span><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">a</span>&nbsp;+= i<br style="max-width: 100%; box-sizing: border-box !important;">end<br style="max-width: 100%; box-sizing: border-box !important;"><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 52px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">0.000006</span>&nbsp;seconds (<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">4</span>&nbsp;allocation<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">s:</span>&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 13px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">64</span>&nbsp;bytes)</code></pre></section><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">但是,如果我们将它放在一个函数中,就可以实现优化。</span>&nbsp;</p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><br></p><section data-mpa-preserve-tpl-color="t" data-mpa-template="t" class="" mpa-preserve="t" style="max-width: 100%; color: rgb(63, 63, 63); font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; box-sizing: border-box !important;"><pre style="max-width: 100%; background: none; box-sizing: border-box !important;"><code class="" style="margin-right: 0.15em; margin-left: 0.15em; padding: 5.95px; max-width: 100%; border-radius: 4px; font-size: 0.85em; background: rgb(40, 44, 52); color: rgb(171, 178, 191); display: block; overflow-x: auto; white-space: nowrap; box-sizing: border-box !important;">function timetest()<br style="max-width: 100%; box-sizing: border-box !important;">a =&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 19px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">3.0</span><br style="max-width: 100%; box-sizing: border-box !important;">@time&nbsp;<span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 19px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">for</span>&nbsp;i =&nbsp;<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">1</span><span class="" style="max-width: 100%; color: rgb(97, 174, 238); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(97, 174, 238); box-sizing: border-box !important;">:</span><span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 7px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">4</span><br style="max-width: 100%; box-sizing: border-box !important;">a += i<br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 19px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">end</span><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(198, 120, 221); background: rgba(0, 0, 0, 0); display: inline; width: 19px; text-decoration-style: solid; text-decoration-color: rgb(198, 120, 221); box-sizing: border-box !important;">end</span><br style="max-width: 100%; box-sizing: border-box !important;">timetest()&nbsp;<span class="" style="max-width: 100%; color: rgb(92, 99, 112); background: rgba(0, 0, 0, 0); display: inline; width: 137px; text-decoration-style: solid; text-decoration-color: rgb(92, 99, 112); font-style: italic; box-sizing: border-box !important;"># First time compiles</span><br style="max-width: 100%; box-sizing: border-box !important;">timetest()<br style="max-width: 100%; box-sizing: border-box !important;"><br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">0</span>.<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 39px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">000001</span>&nbsp;seconds<br style="max-width: 100%; box-sizing: border-box !important;"><span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 6px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">0</span>.<span class="" style="max-width: 100%; color: rgb(209, 154, 102); background: rgba(0, 0, 0, 0); display: inline; width: 39px; text-decoration-style: solid; text-decoration-color: rgb(209, 154, 102); box-sizing: border-box !important;">000000</span>&nbsp;seconds</code></pre></section><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;">这个问题非常容易解决:不要在 REPL 的全局作用域内进行基准测试或计算执行时间。始终将代码放在函数中,或将它们声明为 const。</span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><section style="border-width: 0px;border-style: initial;border-color: initial;clear: both;box-sizing: border-box;" class="tn-Powered-by-XIUMI"><section style="padding: 8px;border-left: 6px solid rgb(255, 202, 0);font-size: 112.5%;line-height: 1.4;font-family: inherit;font-weight: bold;text-decoration: inherit;color: rgb(10, 10, 10);border-top-color: rgb(255, 202, 0);border-right-color: rgb(255, 202, 0);border-bottom-color: rgb(255, 202, 0);box-sizing: border-box;" class="tn-Powered-by-XIUMI"><section class="tn-Powered-by-XIUMI">结论<br></section></section></section><p><span style="font-size: 15px;letter-spacing: 0.5px;"><br></span></p><p style="margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="color: rgb(255, 104, 39);"><strong><span style="font-size: 15px;letter-spacing: 0.5px;">速度是 Julia 的设计目标</span></strong></span><span style="font-size: 15px;letter-spacing: 0.5px;">。类型稳定性和多重分派对 Julia 编译的专门化起到了关键的作用。而要达到如此精细的类型处理水平,以便尽可能有效地实现类型稳定性,并在不完全可能的情况下实现性能优化,需要一个健壮的类型系统。</span></p><p style="padding-top: 23px; padding-right: 8px; padding-left: 8px; max-width: 100%; min-height: 1em; font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; white-space: pre-line; line-height: 27px; color: rgb(74, 74, 74); margin-left: 8px; margin-right: 8px; box-sizing: border-box !important;"><span style="max-width: 100%; color: rgb(136, 136, 136); font-size: 14px; box-sizing: border-box !important;"><strong style="max-width: 100%; box-sizing: border-box !important;">英文原文:</strong></span></p><p style="padding-top: 23px; padding-right: 8px; padding-left: 8px; max-width: 100%; min-height: 1em; font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; white-space: pre-line; line-height: 27px; color: rgb(74, 74, 74); margin-left: 8px; margin-right: 8px; box-sizing: border-box !important;"><span style="color: rgb(136, 136, 136);font-size: 14px;letter-spacing: 0.544px;">https://ucidatascienceinitiative.github.io/IntroToJulia/Html/WhyJulia</span></p><p style="padding-top: 23px; padding-right: 8px; padding-left: 8px; max-width: 100%; min-height: 1em; font-family: Avenir, -apple-system-font, 微软雅黑, sans-serif; font-size: 16px; letter-spacing: 0.544px; white-space: pre-line; line-height: 27px; color: rgb(74, 74, 74); margin-left: 8px; margin-right: 8px; box-sizing: border-box !important;"><span style="color: rgb(136, 136, 136);letter-spacing: 0.544px;font-size: 14px;">本文经授权转载自AI前线,ID:&nbsp;<span style="letter-spacing: 0.5px; text-align: center;">ai-front。</span></span></p><p></p>
页: [1]
查看完整版本: 碾压 Python!为什么 Julia 速度这么快?