Thread overview
[Issue 17485] bringToFront and/or upperBound slow
Dec 17, 2022
Iain Buclaw
June 09, 2017
https://issues.dlang.org/show_bug.cgi?id=17485

Steven Schveighoffer <schveiguy@yahoo.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |performance

--
June 09, 2017
https://issues.dlang.org/show_bug.cgi?id=17485

hsteoh@quickfur.ath.cx changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |hsteoh@quickfur.ath.cx

--- Comment #1 from hsteoh@quickfur.ath.cx ---
>From an initial cursory glance: bringToFrontImpl relies only on forward range
primitives to do its job.  Also, it allows you to transcribe ranges with different element types across each other (as long as the element type is implicitly convertible to the target element type).  While this is all great for generality, it sucks for performance when you're dealing with, e.g., built-in arrays.

I think there should definitely be a specialization for built-in arrays at the very least, if not for slice-assignable random-access ranges in general, when the element types are identical.  Definitely should consider using memmove() in these cases to take advantage of years' worth of work C library authors have put into memmove().

--
June 09, 2017
https://issues.dlang.org/show_bug.cgi?id=17485

--- Comment #2 from hsteoh@quickfur.ath.cx ---
More specifically, if (1) both ranges are built-in arrays, (2) they have the
same element type, and (3) the back range is a single element, we can optimize
this way:

If front and back are disjoint: (front.ptr > back.ptr && front.ptr +
front.length < back.ptr)

-------
ElementType!InputRange e1 = back[0];
back[0] = front[$-1];
memmove(front.ptr+1, front.ptr, front.length-1);
front[0] = e1;
-------

If back is part of front (i.e., front.ptr < back.ptr < front.ptr +
front.length):

--------
ElementType!InputRange e1 = back[0];
memmove(front.ptr+1, front.ptr, back.ptr - front.ptr);
front[0] = e1;
--------

--
June 10, 2017
https://issues.dlang.org/show_bug.cgi?id=17485

--- Comment #3 from Steven Schveighoffer <schveiguy@yahoo.com> ---
Indeed, memmove fixes the specific use case:

https://forums.dlang.org/post/ohgjec$1aar$1@digitalmars.com

However, I think we should do a full examination of everything C++ does to optimize rotate and include it all at once, instead of waiting for people to find more cases where std::rotate outperforms D.

--
December 17, 2022
https://issues.dlang.org/show_bug.cgi?id=17485

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P1                          |P4

--
December 01
https://issues.dlang.org/show_bug.cgi?id=17485

--- Comment #4 from dlangBugzillaToGithub <robert.schadek@posteo.de> ---
THIS ISSUE HAS BEEN MOVED TO GITHUB

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

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

--