wektoryzacji jest, jeśli
- Ułatwia odczyt kodu, a wydajność nie jest równa ritical
- Jeśli jest to operacja algebry liniowej, użycie stylu wektorowego może być dobre, ponieważ Julia może używać BLAS i LAPACK do wykonywania operacji za pomocą bardzo wyspecjalizowanego, wysokowydajnego kodu.
Ogólnie uważam, że najlepiej zacząć od wektoryzacji kodu, szukać problemów z szybkością, a następnie opracować wszelkie kłopotliwe problemy.
Twój drugi kod jest powolny nie tyle ze względu na jego wektoryzację, ale ze względu na użycie anonimowej funkcji: niestety w Julii 0.3 są one zwykle nieco wolniejsze. map
generalnie nie działa zbyt dobrze, wierzę, ponieważ Julia nie może wywnioskować typu wyjściowego funkcji (jej wciąż "anonimowy" z perspektywy funkcji map
). Napisałem inną vectorized wersję, która unika funkcje anonimowe, i to prawdopodobnie nieco łatwiejsze do odczytania:
function determine_pi_vec2(n)
return cumsum((rand(n).^2 .+ rand(n).^2) .<= 1) ./ (1:n)
end
Benchmarking z
function bench(n, f)
f(10)
srand(1000)
@time f(n)
srand(1000)
@time f(n)
srand(1000)
@time f(n)
end
bench(10^8, determine_pi)
gc()
bench(10^8, determine_pi_vec)
gc()
bench(10^8, determine_pi_vec2)
daje mi wyniki
elapsed time: 5.996090409 seconds (800000064 bytes allocated)
elapsed time: 6.028323688 seconds (800000064 bytes allocated)
elapsed time: 6.172004807 seconds (800000064 bytes allocated)
elapsed time: 14.09414031 seconds (8800005224 bytes allocated, 7.69% gc time)
elapsed time: 14.323797823 seconds (8800001272 bytes allocated, 8.61% gc time)
elapsed time: 14.048216404 seconds (8800001272 bytes allocated, 8.46% gc time)
elapsed time: 8.906563284 seconds (5612510776 bytes allocated, 3.21% gc time)
elapsed time: 8.939001114 seconds (5612506184 bytes allocated, 4.25% gc time)
elapsed time: 9.028656043 seconds (5612506184 bytes allocated, 4.23% gc time)
tak vectorized W niektórych przypadkach kod może być równie dobry, jak devectorized, nawet jeśli nie jesteśmy w przypadku linearno-algebry.
Dzięki. Zmieniłem drugi kod, aby usunąć funkcję anonimową, ale jej nadal działa źle: funkcja isInside (x) x <= 1? 1: 0 koniec; funkcja determine_pi_vec (n) res = cumsum (mapa (isInside, rand (n).^2 + rand (n).^2)) ./ [1: n]; return res koniec; @time returnArray2 = determine_pi_vec (n); #czasowy czas: 2.303632751 sekund (880001336 przydzielonych bajtów, 31.88% czasu gc) –
Anonimowa funkcja nie jest największym problemem - bardziej jest, że 'map' nie wstawia argumentów funkcji i generuje wyspecjalizowany kod, podczas gdy unikając mapy, Kontrola isInside może być zaznaczona. – StefanKarpinski
Hah Tak, właśnie zaktualizowałem swoją odpowiedź, próbując wyjaśnić ten punkt: – IainDunning