Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some possible improvements for std.algorithm.schwartzSort() #9581

Open
dlangBugzillaToGithub opened this issue Oct 18, 2010 · 1 comment
Open

Comments

@dlangBugzillaToGithub
Copy link

bearophile_hugs reported this on 2010-10-18T19:11:06Z

Transfered from https://issues.dlang.org/show_bug.cgi?id=5078

CC List

Description

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);
}
@dlangBugzillaToGithub
Copy link
Author

andrei (@andralex) commented on 2013-02-26T09:26:57Z

Bearophile, could you please paste this as a pull request. Thanks!

@LightBender LightBender removed the P4 label Dec 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants