首页 > 解决方案 > 如果从命令行运行 Julia 脚本,是否每次都需要重新编译?

问题描述

我已经阅读了很多文档和问题,但我仍然对此感到困惑。

在文档的Profiling部分中,建议首先在 REPL 中运行目标函数一次,以便它在被分析之前已经编译。但是,如果脚本相当复杂并且打算在命令行中运行并接受参数怎么办?当该julia过程完成并且我第二次运行脚本时,是否再次执行编译?像https://stackoverflow.com/a/42040763/1460448这样的帖子,Julia 每次都编译脚本?给出相互矛盾的答案。当 Julia 不断发展时,它们似乎也很老了。

在我看来,根据我的经验,第二次运行所花费的时间与第一次运行的时间完全相同。启动时间相当长。我应该如何优化这样的程序?添加__precompile__()似乎根本没有改变执行时间。

另外,当我想分析这样的程序时应该怎么做?所有关于分析的资源都在 REPL 中讨论了这样做。

标签: compilationprofilingjuliaread-eval-print-loop

解决方案


我有点不同意我的同事。在某些绝对有效的情况下,人们会依赖运行 Julia 脚本。例如,当您有一个脚本管道(例如 matlab、python 等)并且您需要在所有这些中间的某个地方插入一个 julia 脚本,并从一个 shell 脚本控制整个管道。但是,无论用例如何,说“只使用 REPL”都不是这个问题的正确答案,即使无法提出“有效”的场景,这仍然是一个值得直接回答而不是直接回答的问题一种解决方法。

我同意的是,拥有适当代码的解决方案是将需要预编译的所有关键内容包装到模块中,并且只将除最外部命令之外的所有命令留在脚本顶层。无论如何,这与 matlab 或 C++ 世界并没有太大的不同,在那里您需要编写完整的函数,并且只将您的脚本/主函数视为某种非常简短的顶级入口点,其工作是简单地准备初始环境,然后相应地运行那些更专业的功能。

这是我的意思的一个例子:

# in file 'myscript.jl'
push!( LOAD_PATH, "./" )
import MyPrecompiledModule
println( "Hello from the script. The arguments passed into it were $ARGS" )
MyPrecompiledModule.exportedfun()

# in file 'MyPrecompiledModule.jl' (e.g. in the same directory as myscript.jl)
__precompile__()
module MyPrecompiledModule
  export exportedfun;
  function innerfun()
    println("Hello from MyPrecompiledModule.innerfun");
  end

  function exportedfun()
    innerfun()
    print("Hello from MyPrecompiledModule.exportedfun");
  end
end

在上述场景MyPrecompiledModule中,脚本中将使用编译后的版本(如果不存在,则会在您第一次运行脚本时编译),因此编译后的任何优化都不会在结束时丢失脚本,但您最终仍会得到一个独立的 julia 脚本,您可以将其用作 bash shell 脚本管道过程的一部分,也可以将参数传递给该脚本。然后myscript.jl脚本只需在必要时将这些传递给导入的模块函数,并执行您不特别关心它们是否被编译/优化的任何其他命令,例如执行基准测试、提供脚本使用说明等。


推荐阅读