I am playing with julialang and loving it, but at the same time noticed that they have a benchmark comparison with Mathematica. I have already submited a better version of recursion_fibonacci and now am looking into recursion_quicksort. I would like to find an implementation in Mathematica that is comparable to C-lang.
Currently, the benchmark uses the following code
(* numeric vector sort *) ClearAll[qsort]; (* qsort[ain_, loin_, hiin_] := Module[ {a = ain, i = loin, j = hiin, lo = loin, hi = hiin, pivot}, While[ i < hi, pivot = a[[BitShiftRight[lo + hi] ]]; While[ i <= j, While[a[[i]] < pivot, i++]; While[a[[j]] > pivot, j--]; If[ i <= j, a[[{i,j}]] = a[[{j, i}]]; i++; j--; ]; ]; If[ lo < j, a = qsort[a, lo, j] ]; {lo, j} = {i, hi}; ]; a ]; *) qsort = Compile[ {{ain, _Real, 1}, {loin, _Integer}, {hiin, _Integer}}, Module[ {a = ain, i = loin, j = hiin, lo = loin, hi = hiin, pivot}, While[ i < hi, pivot = a[[ Floor[(lo + hi)/2] ]]; While[ i <= j, While[a[[i]] < pivot, i++]; While[a[[j]] > pivot, j--]; If[ i <= j, a[[{i,j}]] = a[[{j, i}]]; i++; j--; ]; ]; If[ lo < j, a[[lo;;j]] = qsort[ a[[lo;;j]], 1, j - lo + 1] ]; {lo, j} = {i, hi}; ]; a ] ]; ClearAll[sortperf]; sortperf[n_] := Module[{vec = RandomReal[1, n]}, qsort[vec, 1, n]]; test[OrderedQ[sortperf[5000]] ]; timeit[sortperf[5000], "recursion_quicksort"]; where there is compiled and uncompiled versions of quicksort algorithm. On my laptop the compiled version takes 10.3ms, while uncompiled version takes 137.8ms. I think there is space for improvement since the inbuilt method Sort[] takes only 0.379ms.
How do we speed-up the quicksort algorithm? Bonus points if we don't use Compile[]
Helper functions to run the code above
Needs["CCompilerDriver`"]; If[ Length[CCompilers[]] > 0, $CompilationTarget = "C" ]; ClearAll[timeit]; SetAttributes[timeit, HoldFirst]; timeit[ex_, name_String] := Module[ {t}, t = Infinity; Do[ t = Min[t, N[First[AbsoluteTiming[ex]]]]; , {i, 1, 5} ]; If[$printOutput, Print["mathematica,", name, ",", t*1000]; ]; ]; ClearAll[test]; SetAttributes[test, HoldFirst]; test[ex_] := Assert[ex]; On[Assert];
recursive_fibonacci, I assume you use memoization and this is not what the Julia-team wanted to measure with this test. This test is supposed to measure the timing of recursive calls which are horribly slow in Mathematica. I've been there myself when I saw the testing code and asked, who on earth would implement fib like that. As it turns out, for their purpose it is the right way to do it. $\endgroup$matmulexample in the Julia benchmarks is complete bogos.Total[Unitize[A.ConjugateTranspose[A] - 200], 2] == 0performs the task in a tenth of time. Benchmarking matrix multiplication is ridiculous anyways as any reasonable language would delegate that to BLAS routines. Themandelimplementation is notListable. UsingCompilewith optionsCompilationTarget -> "C", RuntimeAttributes -> {Listable}, RuntimeOptions -> "Speed"would make it 10(!) times faster, bringing us much closer to the C performance. $\endgroup$