更新:自从我提出这个问题以来,Julia发生了一些变化。虽然我不再关注Julia的更新,但如果你正在寻找类似的东西,请查看下面的答案和评论,这些人一直在关注Julia。
另外,很高兴知道现在加载一个脚本只需要大约150毫秒。
Keno的回答很准确,但是也许我可以详细说明一下正在发生的事情以及我们计划如何处理。
目前仅存在LLVM JIT模式:
这就是Julia即使没有类型注释编写代码时也能获得良好性能的方式:如果您调用f(1)
,则会得到为Int64
专门设计的代码,64位系统上的1
的类型;如果您调用f(1.0)
,则会得到一种新的及时编译版本,该版本专门针对Float64
——所有系统上1.0
的类型。由于每个函数的已编译版本知道它将要接收的类型,因此它可以以类似于C的速度运行。您可以通过编写和使用“类型不稳定”的函数,使返回类型取决于运行时数据而不仅仅是类型来破坏它,但在设计核心语言和标准库时,我们已经非常小心地避免了这种情况。
大多数Julia都是用自身编写的,然后被解释,类型推断和即时编译,因此从头开始引导整个系统需要大约15-20秒。为了使其更快,我们采用了分阶段系统,在其中解析,类型推断,然后缓存序列化版本的类型推断AST在文件sys.ji
中。然后加载此文件并用于运行julia
系统。但是,没有LLVM代码或机器代码被缓存在sys.ji
中,因此每次julia
启动时仍然需要进行所有LLVM即时编译,因此需要大约2秒钟。
这个2秒的启动延迟相当让人恼火,我们有一个解决计划。基本计划是能够将整个Julia程序编译为二进制文件:可以运行的可执行文件或者可以像使用共享C库一样从其他程序中调用的.so
/.dylib
共享库。二进制文件的启动时间就像任何其他C程序一样,所以2秒的启动延迟将消失。
附录1:自2013年11月起,Julia的开发版本不再有2秒的启动延迟,因为它预编译了标准库作为二进制代码。启动时间仍然比Python和Ruby慢10倍,因此还有改进的空间,但已经相当快了。下一步将允许预编译软件包和脚本,使它们的启动速度与Julia本身一样快。
附录2:自2015年6月起,Julia的开发版本自动预编译了许多软件包,使它们加载速度更快。下一步是对整个Julia程序进行静态编译。
目前Julia在启动时会对其整个标准库进行JIT编译。我们已经意识到这种情况并正在努力缓存LLVM JIT输出以解决此问题,但在此之前,没有其他方法(除了使用REPL)。
julia v0.4
的一个新功能,可以大幅提高模块加载速度。 - Maxim