Issue 5078 - Some possible improvements for std.algorithm.schwartzSort()
Summary: Some possible improvements for std.algorithm.schwartzSort()
Status: ASSIGNED
Alias: None
Product: D
Classification: Unclassified
Component: phobos (show other issues)
Version: D2
Hardware: All All
: P4 enhancement
Assignee: bearophile_hugs
URL:
Keywords: bootcamp, patch
Depends on:
Blocks:
 
Reported: 2010-10-18 19:11 UTC by bearophile_hugs
Modified: 2024-12-01 16:13 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description bearophile_hugs 2010-10-18 19:11:06 UTC
Here I have a (hopefully) improved version of schwartzSort (code not tested much). It contains three changes:

1) I have removed the fields here:
return binaryFun!(less)(a[0], b[0]);

2) I have added a transformFunc, so schwartzSort() may accept a short string too as transform, as sort/map/filter do, like:  schwartzSort!q{ a.y }(data)

3) When the input data is very small it's a waste of time to allocate a temporary array on the GC heap, so I have used alloca().

So this code assumes that the space allocated by alloca() gets freed only at the end of the function, this is a constraint that I think D docs don't state, see bug 3822


See also bug 5077



import std.algorithm: SwapStrategy, zip, sort, binaryFun, unaryFun;
import std.range: isRandomAccessRange, hasLength, front;
import std.c.stdlib: alloca;
import std.array: array;


void schwartzSort(alias transform, alias less = "a < b",
        SwapStrategy ss = SwapStrategy.unstable, Range)(Range r)
    if (isRandomAccessRange!(Range) && hasLength!(Range))
{
    enum size_t MAX_SIZE = 512;
    alias unaryFun!transform transformFunc;

    alias typeof(transformFunc(r.front)) XformType;
    XformType[] xform;
    if (r.length * XformType.sizeof > MAX_SIZE)
    {
        xform = new XformType[r.length];
    }
    else
    {
        xform = (cast(XformType*)alloca(r.length * XformType.sizeof))[0 .. r.length];
    }

    foreach (i, e; r)
    {
        xform[i] = transformFunc(e);
    }
    auto z = zip(xform, r);
    alias typeof(z.front()) ProxyType;
    bool myLess(ProxyType a, ProxyType b)
    {
        return binaryFun!(less)(a[0], b[0]);
    }
    sort!(myLess, ss)(z);
}

// demo code --------------------------

import std.typecons: Tuple;
import std.stdio: writeln;

alias Tuple!(int, "x", int, "y") P;

void main() {
    P[] data = [P(1,4), P(2,3), P(3,1), P(4,0)];
    writeln(data);
//    schwartzSort!((p) { return p.y; })(data);
    schwartzSort!q{ a.y }(data);
    writeln(data);
}
Comment 1 Andrei Alexandrescu 2013-02-26 09:26:57 UTC
Bearophile, could you please paste this as a pull request. Thanks!
Comment 2 dlangBugzillaToGithub 2024-12-01 16:13:37 UTC
THIS ISSUE HAS BEEN MOVED TO GITHUB

https://github.com/dlang/phobos/issues/9581

DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB