What you see is not related to CSV.write
, but to the fact that DataFrame
is type-unstable. This means that it will allocate when iterating rows and accessing their contents. Here is an example:
julia> df = DataFrame(a=1:10000000);
julia> f(x) = x[1]
f (generic function with 1 method)
julia> @time sum(f, eachrow(df)) # after compilation
0.960045 seconds (40.07 M allocations: 613.918 MiB, 4.18% gc time)
50000005000000
This is a deliberate design decision to avoid unacceptable compilation times for very wide data frames (which are common in practice in certain fields of application). Now, this is the way to reduce allocations:
julia> @time CSV.write("test.csv", df) # after compilation
1.976654 seconds (60.00 M allocations: 1.345 GiB, 5.64% gc time)
"test.csv"
julia> @time CSV.write("test.csv", Tables.columntable(df)) # after compilation
0.439597 seconds (36 allocations: 4.002 MiB)
"test.csv"
(this will work OK if the table is narrow, for wide tables it might hit compilation time issues)
This is one of the patterns that are often encountered in Julia (even Julia itself works this way as args
field in Expr
is Vector{Any}
): often you are OK with type unstable code if you do not care about performance (but want to avoid excessive compilation latency), and it is easy to switch to type-stable mode where compilation time does not matter and type-stability does.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…