Jdi na navigaci předmětu

1. Domácí úkol: Porovnání

using DataFrames, CSV, PyPlot

Import naměřených dat.

data = CSV.read("files/measurements.csv", DataFrame);
data[!, :score] = zeros(Int64, nrow(data));

Význam jednotlivých sloupců je následující:

  • dense_time a dense_memory: čas a paměť potřebná k převodu husté Float64 1000×10001000\times1000 matice na rHST.
  • jacobi_time a jacobi_memory: čas a paměť potřebná k převodu tridiagonální Float64 1000×10001000\times1000 matice na rHST.
  • bigint_time a bigint_memory: čas a paměť potřebná k převodu husté BigInt 1000×10001000\times1000 matice na rHST.
  • inverse_time a inverse_memory: čas a paměť potřebná výpočtu inverze husté Float64 500×500500\times500 matice.
  • solve_time a solve_memory: čas a paměť potřebná k vyřešení soustavy s Float64 500×500500\times500 maticí.
  • loc: čistý počet řádků kódu v souboru gauss.jl (tj. bez komentářů a prázdných řádků).

Čas v původních datech je měřen v nanosekundách, paměť v bytech. Každá hodnota je medián několika běhů benchmarku z balíčku BechmarkTools.jl. Všechny výpočty běží na stejných předem vygenerovaných maticích.

Poznámky

  • Vedle studentů je v tabulce i můj řádek (kalvotom) a řádek odpovídající rref metodě z RowEchelon.jl balíčku, která by měla obsahovat původní implementaci v Julia od Jeffa Bezansona (username bezanson; není ale použitelná mimo strojová čísla a v případě invertování a řešení soustavy).
  • U některých studentů v třetím a čtvrtém benchmarku (velká matice s BigInt a inverze větší husté metodě) došlo k chybě (missing hodnoty v tabulce). Detailně jsem chybu neprozkoumával.
  • Pro lepší porovnání časů provedem vždy relativní porovnání s nejrychlejším časem. Měníme proto hodnoty a význam časových sloupců!

Převod na rHST: hustá Float64 matice 1000×10001000\times1000

data[!, :dense_time] /= minimum(data.dense_time);
sort!(data, [:dense_time]);

for k in axes(data, 1)
    data[k, :score] += k
end

data[:, Cols(:username, :dense_time, :dense_memory, :score)]

17 rows × 4 columns

usernamedense_timedense_memoryscore
String15Float64Int64Int64
1Sylean1.001
2kalvotom4.67911167842
3bezanson4.85189163057443
4Syleanlas19.2848166113280004
5Luerailthus21.214246085
6Amalian25.2711240414419046
7Firtherdrim33.8765162641280007
8Ansrael38.502243921447848
9Aeraelael43.7319325410816489
10Ahthievar44.2583251199884810
11Angemar44.86923255399528011
12Aeremarlas45.40713250802483212
13Sumaelran48.43143271868352013
14Yadrimran50.07663251200000014
15Dolkraeslera50.51743252445849615
16Zaevar51.51133250050531216
17Kanthidul51.56163302427142417

Relativní porovnání rychlosti běhu vzhledem k nejrychlejšímu řešení.

plt.grid()
bar(axes(data.dense_time, 1), data.dense_time, tick_label=data.username)
plt.xticks(rotation=80);

Odhad alokace paměti (v bytech).

plt.grid()
bar(axes(data.dense_memory, 1), data.dense_memory, tick_label=data.username)
plt.xticks(rotation=80);

Převod na rHST: tridiagonální Float64 matice 1000×10001000\times1000

data[!, :jacobi_time] /= minimum(data.jacobi_time);
sort!(data, [:jacobi_time]);

for k in axes(data, 1)
    data[k, :score] += k
end

data[:, Cols(:username, :jacobi_time, :jacobi_memory, :score)]

17 rows × 4 columns

usernamejacobi_timejacobi_memoryscore
String15Float64Int64Int64
1Sylean1.002
2Angemar257.787326173246413
3Sumaelran288.706338913096016
4kalvotom326.531167846
5Yadrimran327.473325766988819
6Kanthidul374.83339438195223
7bezanson397.8821630574410
8Syleanlas1350.481661132800012
9Luerailthus1461.552460814
10Amalian1794.92404144190416
11Firtherdrim2365.981626412800018
12Ansrael2847.432439214478420
13Dolkraeslera2939.913252445849628
14Aeraelael3092.013254108164823
15Aeremarlas3136.433250802483227
16Ahthievar3167.733250643929626
17Zaevar3853.93250050531233

Relativní porovnání rychlosti běhu vzhledem k nejrychlejšímu řešení.

plt.grid()
bar(axes(data.jacobi_time, 1), data.jacobi_time, tick_label=data.username)
plt.xticks(rotation=80);

Odhad alokace paměti (v bytech).

plt.grid()
bar(axes(data.jacobi_memory, 1), data.jacobi_memory, tick_label=data.username)
plt.xticks(rotation=80);

Převod na rHST: hustá BigInt matice 1000×10001000\times1000

Počítáme pak v Rational{BigInt}.

mask = .!ismissing.(data.bigint_time);

data[mask, :bigint_time] /= minimum(data[mask, :bigint_time]);
sort!(data, [:bigint_time]);
mask = .!ismissing.(data.bigint_time);

for k in axes(data, 1)
    data[k, :score] += k
end

data[:, Cols(:username, :bigint_time, :bigint_memory, :score)]

17 rows × 4 columns

usernamebigint_timebigint_memoryscore
String15Float64?Int64?Int64
1Syleanlas1.034662572013
2Sylean1.063163033634244
3kalvotom1.073513088545609
4Amalian1.3066863041281620
5Ansrael1.3212463666545625
6Yadrimran1.3395965403536025
7Firtherdrim1.3577262237122425
8Dolkraeslera1.4017165427553636
9Angemar1.4018165620180822
10Zaevar1.4504265449960043
11Kanthidul1.5253565614266434
12Aeremarlas1.5403669683520839
13Ahthievar5.1328117730037639
14Sumaelran5.47222117426160030
15bezansonmissingmissing25
16Luerailthusmissingmissing30
17Aeraelaelmissingmissing40

Relativní porovnání ryuchlosti běhu vzhledem k nejrychlejšímu řešení.

plt.grid()
bar(axes(data[mask, :bigint_time], 1), data[mask, :bigint_time], tick_label=data[mask, :username])
plt.xticks(rotation=80);

Odhad alokace paměti (v bytech).

plt.grid()
bar(axes(data[mask, :bigint_memory], 1), data[mask, :bigint_memory], tick_label=data[mask, :username])
plt.xticks(rotation=80);

Invertování husté 500×500500\times500 matice

mask = .!ismissing.(data.inverse_time);

data[mask, :inverse_time] /= minimum(data[mask, :inverse_time]);
sort!(data, [:inverse_time]);
mask = .!ismissing.(data.inverse_time);

for k in axes(data, 1)
    data[k, :score] += k
end

data[:, Cols(:username, :inverse_time, :inverse_memory, :score)]

17 rows × 4 columns

usernameinverse_timeinverse_memoryscore
String15Float64?Int64?Int64
1Sylean1.042504165
2kalvotom5.39649800876811
3Luerailthus8.471181200904033
4Amalian25.9143602274627224
5Syleanlas29.6776616612243218
6Ansrael36.5642610632296031
7Yadrimran37.5335813600024032
8Aeraelael37.6703815321619248
9Angemar38.0189815680558431
10Ahthievar38.1064813595206449
11Zaevar38.1123812736833654
12Dolkraeslera45.0412813954920048
13Kanthidul55.8287824677112047
14Sumaelran65.9994840893464044
15Aeremarlas1023.892884006606454
16Firtherdrimmissingmissing41
17bezansonmissingmissing42
plt.grid()
bar(axes(data[mask, :inverse_time], 1), data[mask, :inverse_time], tick_label=data[mask, :username])
plt.xticks(rotation=80);
plt.grid()
bar(axes(data[mask, :inverse_memory], 1), data[mask, :inverse_memory], tick_label=data[mask, :username])
plt.xticks(rotation=80);

Řešení soustavy s hustou 500×500500\times500 maticí

mask = .!ismissing.(data.solve_time);

data[mask, :solve_time] /= minimum(data[mask, :solve_time]);
sort!(data, [:solve_time]);
mask = .!ismissing.(data.solve_time);

for k in axes(data, 1)
    data[k, :score] += k
end

data[:, Cols(:username, :solve_time, :solve_memory, :score)]

17 rows × 4 columns

usernamesolve_timesolve_memoryscore
String15Float64?Int64?Int64
1Sylean1.020082726
2kalvotom3.4912202096013
3Luerailthus7.68733201680036
4Firtherdrim29.7404208617243245
5Amalian30.0077301884644829
6Syleanlas40.0174215592835224
7Ansrael40.1764312410899238
8Yadrimran46.7672416200827240
9Aeremarlas47.0253416100532863
10Aeraelael47.2196418118312058
11Angemar47.5359417387704042
12Zaevar48.8256415909417666
13Ahthievar58.7506416817619262
14Kanthidul59.2456427278284861
15Dolkraeslera59.2739417527633663
16Sumaelran62.2772422891345660
17bezansonmissingmissing59
plt.grid()
bar(axes(data[mask, :solve_time], 1), data[mask, :solve_time], tick_label=data[mask, :username])
plt.xticks(rotation=80);
plt.grid()
bar(axes(data[mask, :solve_memory], 1), data[mask, :solve_memory], tick_label=data[mask, :username])
plt.xticks(rotation=80);

Čistý počet řádků kódu v gauss.jl

sort!(data, [:loc]);
mask = .!ismissing.(data.loc);

for k in axes(data, 1)
    data[k, :score] += k
end

data[:, Cols(:username, :loc, :score)]

17 rows × 3 columns

usernamelocscore
String15Int64?Int64
1Kanthidul6062
2Amalian6131
3Firtherdrim6948
4Aeraelael7162
5Angemar7547
6kalvotom8219
7Ansrael8445
8Syleanlas8832
9Zaevar9675
10Dolkraeslera10073
11Sumaelran10071
12Aeremarlas10275
13Yadrimran11453
14Sylean13020
15Luerailthus13451
16Ahthievar15478
17bezansonmissing76
plt.grid()
bar(axes(data[mask, :loc], 1), data[mask, :loc], tick_label=data[mask, :username])
plt.xticks(rotation=80);

Skóre (čím menší hodnota, tím lépe)

sort!(data, :score)
data[:, :points] = zeros(Int64, nrow(data))

n = 0
for k in axes(data, 1)
    # kalvotom a bezanson se nepočítají, zbývá 15 studentů
    if data[k, :username] == "kalvotom" || data[k, :username] == "bezanson"
        continue
    end
    
    data[k, :points] = 5 - div(n, 5)
    n += 1
end

data[:, Cols(:username, :score, :points)]

17 rows × 3 columns

usernamescorepoints
String15Int64Int64
1kalvotom190
2Sylean205
3Amalian315
4Syleanlas325
5Ansrael455
6Angemar475
7Firtherdrim484
8Luerailthus514
9Yadrimran534
10Kanthidul624
11Aeraelael624
12Sumaelran713
13Dolkraeslera733
14Zaevar753
15Aeremarlas753
16bezanson760
17Ahthievar783