Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Julia loss of performance after importing unrelated package

I get a performance hit to deepcopy once I import an unrelated package, CSV. How can I fix this?

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

UPDATE: Code for suggested solution

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
like image 702
Gabi Avatar asked Feb 20 '19 14:02

Gabi


1 Answers

There are at least two possibilities:

  • Something in your code requires run-time dispatch. Importing CSV adds new methods, thus making the method tables for one or more of your key functions longer. Since run-time dispatch then has more possibilities to evaluate, it makes it slower. Solution: make sure your code is "type stable" (inferrable) wherever possible, then Julia won't need to perform run-time dispatch. See the Performance tips page to get started.
  • Something in CSV is doing type-piracy, and its implementation is slowing you down.

I would place my bets on the former. Use ProfileView.jl to easily detect run-time dispatch graphically. If you see a lot of red bars on top when you profile rungame, then you know you've found the source of the problems. Aside from the interaction with CSV, eliminating those red bars might give you huge improvements in performance.

like image 139
tholy Avatar answered Nov 05 '22 06:11

tholy