Anonymous user
Sorting algorithms/Quicksort: Difference between revisions
→{{header|Raku}}
imported>Rcmlz |
imported>Rcmlz |
||
Line 8,229:
<syntaxhighlight lang="raku" line>
#| Recursive, single-thread, single-pass, quicksort implementation
return @a if @a.elems < 2;
multi quicksort(@unsorted) {▼
my $pivot = @
my %
|samewith(%
}
</syntaxhighlight>
Line 8,240:
<syntaxhighlight lang="raku" line>
#|
return @a if @a.elems < 2;
multi seven-line-quicksort-parallel(@unsorted) {▼
my $pivot = @
my %
my Promise $less = start { samewith(%
my $more = samewith(%
await $less andthen |$less.result, |%
}
</syntaxhighlight>
Let's tune the parallel execution by
<syntaxhighlight lang="raku" line>
#| Recursive, parallel, batch tuned, single-pass, quicksort implementation▼
return @a if @a.elems < 2;
▲#| Recursive, parallel, tuned, single-pass, quicksort implementation
▲multi quicksort-parallel(@unsorted) {
# separate unsorted input into Order Less, Same and More compared to a random $pivot
my $pivot = @
my %
#
my $less =
?? start { samewith(%
# meanwhile use current thread for sorting the More partition
my $more = samewith(%
# if we went parallel, we need to await the result
Line 8,283 ⟶ 8,274:
# concat all sorted partitions into a list and return
|$less, |%
}
</syntaxhighlight>
Line 8,290 ⟶ 8,281:
<syntaxhighlight lang="raku" line>
say "x" x 10 ~ " Testing " ~ "x" x 10;
use Test;
my @
my @testcases =
() => (),
<a>.List => <a>.List,
<a a> => <a a>,
<h b a c d f e g> => <a b c d e f g h>,
<a 🎮 3 z 4 🐧> => <a 🎮 3 z 4 🐧>.sort
;
▲my @implementations = &quicksort, &seven-line-quicksort-parallel, &quicksort-parallel;
plan @testcases.elems * @
for @
say &fun.name;
is-deeply &fun(.key), .value, .key ~ " => " ~ .value for @testcases;
Line 8,310 ⟶ 8,301:
</syntaxhighlight>
<pre>
xxxxxxxxxx Testing xxxxxxxxxx
1..
quicksort
ok 1 - =>
ok 2 - a => a
ok 3 - a a => a a
ok 4 - b a
ok 5 - h b a c d f e g => a b c d e f g h
ok 6 -
ok
▲seven-line-quicksort-parallel
ok 9 - a a => a a
ok 10 - b a 3 => 3 a b
ok 11 -
ok 12 - a
▲ok 13 - b a => a b
quicksort-parallel
ok
ok
ok
ok
ok
ok
</pre>▼
and some benchmarking
<syntaxhighlight lang="raku" line>
say "x" x 11 ~ " Benchmarking " ~ "x" x 11;
use Benchmark;
my @large of Str = ('a'..'z').roll($elem-length).join xx 10 * $worker * $BATCH-SIZE;▼
my $runs = 5;
my $elems = 10 * Kernel.cpu-cores * 2**10;
my UInt $l-batch = 2**13;
my UInt $m-batch = 2**11;
my UInt $s-batch = 2**9;
my UInt $t-batch = 2**7;
say "elements: $elems, runs: $runs, cpu-cores: {Kernel.cpu-cores}, large/medium/small/tiny-batch: $l-batch/$m-batch/$s-batch/$t-batch";
my %results = timethese $runs, {
parallel-naive => { quicksort-parallel-naive(@unsorted) },
}▼
parallel-small-batch => { quicksort-parallel(@unsorted, $s-batch) },
</syntaxhighlight>▼
parallel-medium-batch => { quicksort-parallel(@unsorted, $m-batch) },
parallel-large-batch => { quicksort-parallel(@unsorted, $l-batch) },
▲};
for %results.kv -> $name, ($start, $end, $diff, $avg) {
say "$name avg $avg secs"
▲}</syntaxhighlight>
<pre>
xxxxxxxxxxx Benchmarking xxxxxxxxxxx
elements: 40960, runs: 5, cpu-cores: 4, large/medium/small/tiny-batch: 8192/2048/512/128
single-thread avg 6 secs
parallel-naive avg 5.6 secs
parallel-tiny-batch avg 2.8 secs
parallel-small-batch avg 2.4 secs
parallel-medium-batch avg 2.8 secs
parallel-large-batch avg 3.4 secs
▲</pre>
=={{header|Red}}==
|