Skip to content

Commit 0fbc200

Browse files
committed
update benchmarks
1 parent fbc9e30 commit 0fbc200

4 files changed

Lines changed: 35 additions & 17 deletions

File tree

benchmark/benchmark.jl

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using DataFrames, Random, CategoricalArrays
22
@time using FixedEffectModels
3-
# 13s precompiling
3+
# 0.418712 seconds (742.49 k allocations: 45.500 MiB, 4.07% gc time, 1.07% compilation time)
44
# Very simple setup
55
N = 10000000
66
K = 100
@@ -12,21 +12,21 @@ y= 3 .* x1 .+ 5 .* x2 .+ cos.(id1) .+ cos.(id2).^2 .+ randn(N)
1212
df = DataFrame(id1 = id1, id2 = id2, x1 = x1, x2 = x2, y = y)
1313
# first time
1414
@time reg(df, @formula(y ~ x1 + x2))
15-
# 1.823s
15+
# 1.810739 seconds (14.05 M allocations: 1.583 GiB, 3.76% gc time, 84.28% compilation time: 91% of which was recompilation)
1616
@time reg(df, @formula(y ~ x1 + x2))
17-
# 0.353469 seconds (441 allocations: 691.439 MiB, 3.65% gc time)
17+
# 0.288344 seconds (712 allocations: 920.405 MiB, 18.71% gc time)
1818
@time reg(df, @formula(y ~ x1 + x2), Vcov.cluster(:id2))
19-
# 0.763999 seconds (2.96 M allocations: 967.418 MiB, 2.29% gc time, 54.39% compilation time: 5% of which was recompilation)
19+
# 0.528590 seconds (1.33 M allocations: 1.039 GiB, 8.76% gc time, 55.33% compilation time)
2020
@time reg(df, @formula(y ~ x1 + x2), Vcov.cluster(:id2))
21-
# 0.401544 seconds (622 allocations: 768.943 MiB, 3.52% gc time)
21+
# 0.268619 seconds (879 allocations: 997.916 MiB, 15.08% gc time)
2222
@time reg(df, @formula(y ~ x1 + x2 + fe(id1)))
23-
# 0.893835 seconds (1.03 k allocations: 929.130 MiB, 54.19% gc time)
23+
# 0.824536 seconds (3.09 M allocations: 1.426 GiB, 5.37% gc time, 61.39% compilation time: 3% of which was recompilation)
2424
@time reg(df, @formula(y ~ x1 + x2 + fe(id1)))
25-
# 0.474160 seconds (1.13 k allocations: 933.340 MiB, 1.74% gc time)
25+
# 0.356793 seconds (1.41 k allocations: 1.276 GiB, 19.31% gc time)
2626
@time reg(df, @formula(y ~ x1 + x2 + fe(id1)), Vcov.cluster(:id1))
27-
# 0.598816 seconds (261.08 k allocations: 1.007 GiB, 8.29% gc time, 9.21% compilation time)
27+
# 0.435500 seconds (495.96 k allocations: 1.381 GiB, 15.97% gc time, 10.72% compilation time)
2828
@time reg(df, @formula(y ~ x1 + x2 + fe(id1) + fe(id2)))
29-
# 1.584573 seconds (489.64 k allocations: 1.094 GiB, 2.10% gc time, 8.53% compilation time)
29+
# 1.367264 seconds (1.91 M allocations: 1.592 GiB, 5.74% gc time, 23.85% compilation time: 20% of which was recompilation)
3030

3131
# More complicated setup
3232
N = 800000 # number of observations
@@ -39,9 +39,7 @@ x2 = cos.(id1) + sin.(id2) + randn(N)
3939
y= 3 .* x1 .+ 5 .* x2 .+ cos.(id1) .+ cos.(id2).^2 .+ randn(N)
4040
df = DataFrame(id1 = id1, id2 = id2, x1 = x1, x2 = x2, y = y)
4141
@time reg(df, @formula(y ~ x1 + x2 + fe(id1) + fe(id2)))
42-
# 2.504294 seconds (75.83 k allocations: 95.525 MiB, 0.23% gc time)
43-
# for some reason in 1.10 I now get worse time (iter 200)
44-
# 4.709078 seconds (108.98 k allocations: 101.417 MiB)
42+
# 1.546023 seconds (19.89 k allocations: 119.673 MiB, 1.70% gc time)
4543

4644

4745

@@ -57,8 +55,8 @@ X1 = rand(n)
5755
ln_y = 3 .* X1 .+ rand(n)
5856
df = DataFrame(X1 = X1, ln_y = ln_y, id1 = id1, id2 = id2, id3 = id3)
5957
@time reg(df, @formula(ln_y ~ X1 + fe(id1)), Vcov.cluster(:id1))
60-
# 0.543996 seconds (873 allocations: 815.677 MiB, 34.15% gc time)
58+
# 0.311420 seconds (1.35 k allocations: 1.052 GiB, 22.30% gc time)
6159
@time reg(df, @formula(ln_y ~ X1 + fe(id1) + fe(id2)), Vcov.cluster(:id1))
62-
# 1.301908 seconds (3.03 k allocations: 968.729 MiB, 25.84% gc time)
60+
# 0.808992 seconds (3.52 k allocations: 1.272 GiB, 8.68% gc time)
6361
@time reg(df, @formula(ln_y ~ X1 + fe(id1) + fe(id2) + fe(id3)), Vcov.cluster(:id1))
64-
# 1.658832 seconds (4.17 k allocations: 1.095 GiB, 29.78% gc time)
62+
# 0.950808 seconds (4.75 k allocations: 1.496 GiB, 7.48% gc time)

benchmark/benchmark.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Code to reproduce this graph:
66
FixedEffectModels.jl v1.9.0 (Julia 1.9)
77
```julia
88
using DataFrames, CategoricalArrays, FixedEffectModels
9-
N = 10000000
9+
N = 10_000_000
1010
K = 100
1111
id1 = rand(1:(N/K), N)
1212
id2 = rand(1:K, N)

benchmark/benchmark_Metal.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
using DataFrames, Random, Metal, FixedEffectModels
2+
Random.seed!(1234)
3+
# More complicated setup
4+
N = 8_000_000 # number of observations
5+
M = 400_000 # number of workers
6+
O = 50_000 # number of firms
7+
id1 = rand(1:M, N)
8+
id2 = [rand(max(1, div(x, 8)-10):min(O, div(x, 8)+10)) for x in id1]
9+
x1 = 5 * cos.(id1) + 5 * sin.(id2) + randn(N)
10+
x2 = cos.(id1) + sin.(id2) + randn(N)
11+
x3 = cos.(id1) + sin.(id2) + randn(N)
12+
y= 3 .* x1 .+ 5 .* x2 .+ cos.(id1) .+ cos.(id2).^2 .+ randn(N)
13+
df = DataFrame(id1 = id1, id2 = id2, x1 = x1, x2 = x2, x3 = x3, y = y)
14+
@time reg(df, @formula(y ~ x1 + x2 + x3 + fe(id1) + fe(id2)), maxiter = 200, double_precision = false)
15+
# 30.002852 seconds (66.42 M allocations: 4.917 GiB, 0.83% gc time, 16.25% compilation time: 6% of which was recompilation)
16+
@time reg(df, @formula(y ~ x1 + x2 + x3 + fe(id1) + fe(id2)), method = :Metal, maxiter = 200)
17+
# 16.634684 seconds (3.50 M allocations: 1.407 GiB, 0.69% gc time, 1.49% compilation time: <1% of which was recompilation)
18+
19+
20+

benchmark/result.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
using DataFrames, CSV, Gadflydf = CSV.read("/Users/matthieugomez/Dropbox/Github/FixedEffectModels.jl/benchmark/benchmark.csv", DataFrame)df."fixest (R)" = df."fixest (R)" ./ df."FixedEffectModels.jl (Julia)"df."lfe (R)" = df."lfe (R)" ./ df."FixedEffectModels.jl (Julia)"df."reghdfe (Stata)" = df."reghdfe (Stata)" ./ df."FixedEffectModels.jl (Julia)"df."FixedEffectModels.jl (Julia)" = df."FixedEffectModels.jl (Julia)" ./ df."FixedEffectModels.jl (Julia)"mdf = stack(df, Not([:Command, :Order]))mdf = rename(mdf, :variable => :Language)p = plot(mdf, x = "Command", y = "value", color = "Language", Guide.ylabel("Time (Ratio to Julia)"), Guide.xlabel("Command"), Scale.y_log10)draw(PNG("/Users/matthieugomez/Dropbox/Github/FixedEffectModels.jl/benchmark/fixedeffectmodels_benchmark.png", 8inch, 5inch, dpi=300), p)
1+
using DataFrames, CSV, StatsPlotsdf = CSV.read("/Users/matthieugomez/Dropbox/Github/FixedEffectModels.jl/benchmark/benchmark2.csv", DataFrame)df."fixest (R)" = df."fixest (R)" ./ df."FixedEffectModels.jl (Julia)"df."lfe (R)" = df."lfe (R)" ./ df."FixedEffectModels.jl (Julia)"df."reg / reghdfe (Stata)" = df."reg / reghdfe (Stata)" ./ df."FixedEffectModels.jl (Julia)"df."FixedEffectModels.jl (Julia)" = df."FixedEffectModels.jl (Julia)" ./ df."FixedEffectModels.jl (Julia)"mdf = stack(df, Not([:Command, :Order]))mdf = rename(mdf, :variable => :Language)p = @df mdf plot( :Command, :value, group = :Language, yaxis = :log10, xlabel = "Command", ylabel = "Time (Ratio to Julia)", legend = :top, seriestype = :scatter, # or :line / :path depending on what you want palette = :tol_light, dpi = 200, size=(8 * 100 * 2 /3, 5 * 100 * 2 /3))savefig("/Users/matthieugomez/Dropbox/Github/FixedEffectModels.jl/benchmark/fixedeffectmodels_benchmark.png")

0 commit comments

Comments
 (0)