Julia导入不相关的包后性能下降

Gab*_*abi 8 performance julia data-science

deepcopy一旦我导入一个不相关的包,我的性能就会受到影响CSV.我怎样才能解决这个问题?

import BenchmarkTools
mutable struct GameState
    gameScore::Vector{Int64}
    setScore::Vector{Int64}
    matchScore::Vector{Int64}
    serve::Int64
end
BenchmarkTools.@benchmark deepcopy(GameState([0,0],[0,0],[0,0],-1))

BenchmarkTools.Trial: 
  memory estimate:  1.02 KiB
  allocs estimate:  10
  --------------
  minimum time:     1.585 ?s (0.00% GC)
  median time:      1.678 ?s (0.00% GC)
  mean time:        2.519 ?s (27.10% GC)
  maximum time:     5.206 ms (99.88% GC)
  --------------
  samples:          10000
  evals/sample:     10

import CSV

BenchmarkTools.@benchmark deepcopy(GameState([0,0],[0,0],[0,0],-1))

BenchmarkTools.Trial: 
  memory estimate:  1.02 KiB
  allocs estimate:  10
  --------------
  minimum time:     6.709 ?s (0.00% GC)
  median time:      7.264 ?s (0.00% GC)
  mean time:        9.122 ?s (18.00% GC)
  maximum time:     13.289 ms (99.87% GC)
  --------------
  samples:          10000
  evals/sample:     5
Run Code Online (Sandbox Code Playgroud)

更新:建议解决方案的代码

import Base:deepcopy
function deepcopy(x::GameState)
    return GameState([x.gameScore[1], x.gameScore[2]], [x.setScore[1], x.setScore[2]], [x.matchScore[1], x.matchScore[2]],x.serve)
end

BenchmarkTools.@benchmark deepcopy(GameState([0,0],[0,0],[0,0],-1))
BenchmarkTools.Trial: 
  memory estimate:  672 bytes
  allocs estimate:  8
  --------------
  minimum time:     184.436 ns (0.00% GC)
  median time:      199.305 ns (0.00% GC)
  mean time:        256.366 ns (21.29% GC)
  maximum time:     102.345 ?s (99.52% GC)
  --------------
  samples:          10000
  evals/sample:     656
Run Code Online (Sandbox Code Playgroud)

tho*_*oly 10

至少有两种可能性:

  • 代码中的某些内容需要运行时调度.导入CSV会添加新方法,从而使一个或多个关键函数的方法表更长.由于运行时调度具有更多评估可能性,因此速度较慢.解决方案:确保您的代码尽可能"类型稳定"(可推断),然后Julia将不需要执行运行时调度.请参阅性能提示页面以开始使用.
  • CSV中的某些东西正在进行类型盗版,它的实现正在减慢你的速度.

我会把我的赌注押在前者身上.使用ProfileView.jl以图形方式轻松检测运行时分派.如果您在配置文件时看到很多红色条形图rungame,那么您就知道已找到问题的根源.除了与CSV的交互之外,消除那些红条可能会给您带来巨大的性能提升.

  • 太棒了,这确实帮助找到了罪魁祸首.它似乎大大减慢了深度扫描.我现在已经更新了问题中的代码,所以现在它没有其他依赖项,所以一切都完全可见.问题是 - 如何解决这种放缓问题?:) (3认同)
  • 我不认为动态调度是朱莉娅的关键特征是公平的.事实上,思考Julia的一种方法是它允许静态调度,同时保持对语言的动态感觉.这是通过类型推断和多次调度启用的(这是你在想什么?).动态调度总是很慢,并且应该在perf关键代码中避免(这就是关于类型稳定性的规则归结为).不幸的是,深度复制必然是不稳定的.但好消息是,朱莉娅已经拥有了理解和解决这些案例的工具. (2认同)
  • 另外,我们有一个很棒的社区,可以让你的代码在几个小时内快8倍:) (2认同)