Data update
This commit is contained in:
parent
796d366b97
commit
35bcdeebf8
504 changed files with 7045 additions and 610 deletions
|
|
@ -0,0 +1,7 @@
|
|||
#| Recursive, single-thread, single-pass, quicksort implementation
|
||||
multi quicksort(@unsorted where @unsorted.elems < 2) { @unsorted }
|
||||
multi quicksort(@unsorted) {
|
||||
my $pivot = @unsorted.pick;
|
||||
my %class{Order} is default([]) = @unsorted.classify: * cmp $pivot;
|
||||
|samewith(%class{Less}), |%class{Same}, |samewith(%class{More})
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
#| 7-Line, recursive, parallel, single-pass, quicksort implementation
|
||||
multi seven-line-quicksort-parallel(@unsorted where @unsorted.elems < 2) { @unsorted }
|
||||
multi seven-line-quicksort-parallel(@unsorted) {
|
||||
my $pivot = @unsorted.pick;
|
||||
my %partitions{Order} is default([]) = @unsorted.classify( * cmp $pivot );
|
||||
my Promise $less = start { samewith(%partitions{Less}) }
|
||||
my $more = samewith(%partitions{More});
|
||||
await $less andthen |$less.result, |%partitions{Same}, |$more;
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
constant $BATCH-SIZE = 2**10;
|
||||
my atomicint $worker = $*KERNEL.cpu-cores;
|
||||
#| Recursive, parallel, tuned, single-pass, quicksort implementation
|
||||
proto quicksort-parallel(| --> Positional) {*}
|
||||
multi quicksort-parallel(@unsorted where @unsorted.elems < 2) { @unsorted }
|
||||
multi quicksort-parallel(@unsorted) {
|
||||
# separate unsorted input into Order Less, Same and More compared to a random $pivot
|
||||
my $pivot = @unsorted.pick;
|
||||
my %partitions{Order} is default([]) = @unsorted.classify( * cmp $pivot );
|
||||
|
||||
# atomically decide if we sort the Less partition on a new thread
|
||||
my $less = ⚛$worker > 0 &&
|
||||
%partitions{Less}.elems > $BATCH-SIZE
|
||||
?? (
|
||||
$worker⚛--;
|
||||
start {
|
||||
LEAVE $worker⚛++;
|
||||
samewith(%partitions{Less})
|
||||
}
|
||||
)
|
||||
!! samewith(%partitions{Less});
|
||||
|
||||
# meanwhile use current thread for sorting the More partition
|
||||
my $more = samewith(%partitions{More});
|
||||
|
||||
# if we went parallel, we need to await the result
|
||||
await $less andthen $less = $less.result if $less ~~ Promise;
|
||||
|
||||
# concat all sorted partitions into a list and return
|
||||
|$less, |%partitions{Same}, |$more;
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
use Test;
|
||||
my @testcases =
|
||||
() => (),
|
||||
<a>.List => <a>.List,
|
||||
<a a> => <a a>,
|
||||
<a b> => <a b>,
|
||||
<b a> => <a b>,
|
||||
<h b a c d f e g> => <a b c d e f g h>,
|
||||
(2, 3, 1, 4, 5) => (1, 2, 3, 4, 5),
|
||||
<a 🎮 3 z 4 🐧> => <a 🎮 3 z 4 🐧>.sort
|
||||
;
|
||||
my @implementations = &quicksort, &seven-line-quicksort-parallel, &quicksort-parallel;
|
||||
plan @testcases.elems * @implementations.elems;
|
||||
for @implementations -> &fun {
|
||||
say &fun.name;
|
||||
is-deeply &fun(.key), .value, .key ~ " => " ~ .value for @testcases;
|
||||
}
|
||||
done-testing;
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
my $elem-length = 8;
|
||||
my @large of Str = ('a'..'z').roll($elem-length).join xx 10 * $worker * $BATCH-SIZE;
|
||||
|
||||
say "Benchmarking by sorting {@large.elems} strings of size $elem-length - using batches of $BATCH-SIZE strings and $worker workers.";
|
||||
my @benchmark = gather for @implementations -> &fun {
|
||||
&fun(@large);
|
||||
take (&fun.name => now - ENTER now);
|
||||
}
|
||||
say @benchmark;
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
# Empty list sorts to the empty list
|
||||
multi quicksort([]) { () }
|
||||
|
||||
# Otherwise, extract first item as pivot...
|
||||
multi quicksort([$pivot, *@rest]) {
|
||||
# Partition.
|
||||
my $before := @rest.grep(* before $pivot);
|
||||
my $after := @rest.grep(* !before $pivot);
|
||||
|
||||
# Sort the partitions.
|
||||
flat quicksort($before), $pivot, quicksort($after)
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn quicksort(comptime t: type, arr: []t) void {
|
||||
if (arr.len < 2) return;
|
||||
var pivot = arr[@as(usize, @intFromFloat(@floor(@as(f64, @floatFromInt(arr.len)) / 2)))];
|
||||
var left: usize = 0;
|
||||
var right: usize = arr.len - 1;
|
||||
|
||||
while (left <= right) {
|
||||
while (arr[left] < pivot) {
|
||||
left += 1;
|
||||
}
|
||||
while (arr[right] > pivot) {
|
||||
right -= 1;
|
||||
}
|
||||
if (left <= right) {
|
||||
const tmp = arr[left];
|
||||
arr[left] = arr[right];
|
||||
arr[right] = tmp;
|
||||
left += 1;
|
||||
right -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
quicksort(t, arr[0 .. right + 1]);
|
||||
quicksort(t, arr[left..]);
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
const LIST_TYPE = i16;
|
||||
var arr: [10]LIST_TYPE = [_]LIST_TYPE{ 4, 65, 2, -31, 0, 99, 2, 83, 782, 1 };
|
||||
var i: usize = 0;
|
||||
|
||||
while (i < arr.len) : (i += 1) {
|
||||
std.debug.print("{d} ", .{arr[i]});
|
||||
}
|
||||
std.debug.print("\n", .{});
|
||||
|
||||
i = 0;
|
||||
quicksort(LIST_TYPE, &arr);
|
||||
while (i < arr.len) : (i += 1) {
|
||||
std.debug.print("{d} ", .{arr[i]});
|
||||
}
|
||||
std.debug.print("\n", .{});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue