关于效果:第一次拨打Julia的电话很慢

First call to Julia is slow

这个问题涉及Julia的首次加载性能

我正在从命令行运行Julia程序。该程序旨在成为一个API,其中API的用户不必初始化内部对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
module Internal
   type X
     c::T1
     d::T2
     .
     ..
   end

   function do_something(a::X, arg:Any)
     #some function
   end
   export do_something
end

API.jl

1
2
3
4
5
6
7
using Internal

const i_of_X = X()

function wrapper_do_something(args::Any)
     do_something(i_of_X, args)
end

现在,此API.jl向第三方用户公开,因此他们不必费心实例化内部对象。但是,API.jl不是模块,因此无法进行预编译。由于API.jl中有许多功能,因此第一次加载会花费"非常"的长时间。

有没有办法提高性能?我也尝试将API.jl包装在模块中,但是我不知道将const初始化变量包装在模块中是否可行。这样我也会遇到分段错误(某些const是数据库连接和数据库集合以及其他复杂对象)。

  • 我在OSX上使用v0.5

[编辑]
我确实将API.jl包装在一个模块中,但是并没有提高性能。

  • 我进行了更深入的研究,第一次调用线性回归函数(基于GLM模块的OLS lm(y~X, df))对性能产生了重大影响。 df只有2列和3行,所以这不是运行时问题,而是编译慢。
  • 另一个大打击来自调用高度重载的函数。重载函数从数据库中获取数据,并且可以接受各种输入格式。

有没有办法加快这些速度?有没有办法完全预编译julia程序?

为了获得更多背景知识,基于API的程序将通过命令行调用一次,并且在命令行关闭Julia进程时,任何持久的首次编译优势都将丢失。

1
$julia run_api_based_main_func.jl

利用编译好处的一种怪异方法是以某种方式在已经活跃的julia流程中复制/粘贴代码。这是可行的还是建议的?(我迫切地想快一点。等待15-20秒进行2秒分析似乎不正确)


可以将const值包装在模块中。 它们可以根据需要导出。

正如凤阳所说,将较大设计的独立组件包装在模块中会有所帮助,并且在这种情况下会有所帮助。 当模块内部发生大量事情时,每次初始函数调用所伴随的预编译时间就会加起来。 有一种避免这种情况的方法-在using模块之前预编译内容:

1
2
3
4
5
__precompile__(true)

module ModuleName
# ...
end # module ModuleName

请注意(来自在线帮助):

__precompile__() should not be used in a module unless all of its dependencies are also using __precompile__(). Failure to do so can
result in a runtime error when loading the module.