我注意到在Julia中使用匿名函數的性能損失。爲了說明我有兩個quicksort的實現(從Julia分佈的微觀性能基準中獲得)。所述第一按升序排序在Julia中使用匿名函數的性能損失
function qsort!(a,lo,hi)
i, j = lo, hi
while i < hi
pivot = a[(lo+hi)>>>1]
while i <= j
while a[i] < pivot; i += 1; end
while pivot < a[j]; j -= 1; end
if i <= j
a[i], a[j] = a[j], a[i]
i, j = i+1, j-1
end
end
if lo < j; qsort!(a,lo,j); end
lo, j = i, hi
end
return a
end
第二需要一個附加的參數:可用於指定升序或降序排序,或比較用於更特殊的類型
function qsort_generic!(a,lo,hi,op=(x,y)->x<y)
i, j = lo, hi
while i < hi
pivot = a[(lo+hi)>>>1]
while i <= j
while op(a[i], pivot); i += 1; end
while op(pivot, a[j]); j -= 1; end
if i <= j
a[i], a[j] = a[j], a[i]
i, j = i+1, j-1
end
end
if lo < j; qsort_generic!(a,lo,j,op); end
lo, j = i, hi
end
return a
end
有一個匿名函數當對Int64的數組進行排序時,性能會受到嚴重影響,默認版本的速度要快一個數量級。下面是時間(秒)排序的長度N數組:
N qsort_generic qsort
2048 0.00125 0.00018
4096 0.00278 0.00029
8192 0.00615 0.00061
16384 0.01184 0.00119
32768 0.04482 0.00247
65536 0.07773 0.00490
的問題是:這是由於將在時間待熨燙出在編譯器的限制,或是否有傳遞函子的慣用方式/應該在這種情況下使用的匿名函數?
更新從答案看來,這是一種將在編譯器中解決的問題。
與此同時,有兩個建議的解決方法。這兩種方法都相當簡單,儘管它們開始感覺像是你必須在C++中使用的那種jiggery-pokery(儘管它們的規模並不那麼尷尬)。
第一個是由@Toivo Henningsson建議的FastAnon軟件包。我沒有嘗試這種方法,但看起來不錯。
我試用了@simonstar建議的第二種方法,它給了我與非通用qsort相當的性能!執行:
abstract OrderingOp
immutable AscendingOp<:OrderingOp end
immutable DescendingOp<:OrderingOp end
evaluate(::AscendingOp, x, y) = x<y
evaluate(::DescendingOp, x, y) = x>y
function qsort_generic!(a,lo,hi,op=AscendingOp())
i, j = lo, hi
while i < hi
pivot = a[(lo+hi)>>>1]
while i <= j
while evaluate(op, a[i], pivot); i += 1; end
while evaluate(op, pivot, a[j]); j -= 1; end
if i <= j
a[i], a[j] = a[j], a[i]
i, j = i+1, j-1
end
end
if lo < j; qsort_generic!(a,lo,j,op); end
lo, j = i, hi
end
return a
end
謝謝大家的幫助。
看起來像一個非常簡單的答案OP的問題給我。當然,這看起來不是對問題的批評,也不是要求澄清。 – 2014-10-03 12:29:50
謝謝Stefan。很高興知道,沒有任何理由這樣的匿名函數不能很快採用「小技巧」。 – bcumming 2014-10-04 10:18:53