-
Notifications
You must be signed in to change notification settings - Fork 48
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
Optimized sort #202
Optimized sort #202
Conversation
```cpp using list = brigand::sort<brigand::range<int, 0, SIZE>>; ``` gcc-5.4.0: Size = | 10 | 50 | 100 | 200 | 300 | 500 ------ | ----------- | ----------- | ------------ | ------------ | ------------ | ------------ before | 0.07s - 26M | 0.21s - 75M | 0.42s - 148M | 1.19s - 344M | 2.28s - 609M | 4.00s - 1011M after | 0.05s - 21M | 0.12s - 34M | 0.23s - 56M | 0.58s - 125M | 1.20s - 233M | 2.45s - 393M gain | 28% - 20% | 42% - 54% | 45% - 61% | 51% - 63% | 47% - 61% | 38% - 61% clang-3.8.0: Size = | 10 | 50 | 100 | 200 | 300 | 500 ------ | ----------- | ----------- | ----------- | ----------- | ------------ | ------------ before | 0.09s - 40M | 0.15s - 45M | 0.26s - 54M | 0.66s - 95M | 1.38s - 180M | 2.49s - 321M after | 0.09s - 41M | 0.15s - 45M | 0.25s - 54M | 0.64s - 94M | 1.32s - 178M | 2.42s - 317M gain | 0% - -1% | 0% - 0% | 3% - 0% | 3% - 0% | 4% - 1% | 2% - 1% ```cpp using list = brigand::sort<brigand::reverse_range<int, SIZE, 0>>; ``` gcc-5.4.0: Size = | 10 | 50 | 100 | 200 | 300 | 500 ------ | ----------- | ----------- | ----------- | ------------ | ------------ | ------------ before | 0.05s - 21M | 0.13s - 49M | 0.25s - 83M | 0.46s - 152M | 0.70s - 223M | 1.37s - 375M after | 0.05s - 19M | 0.10s - 29M | 0.14s - 40M | 0.27s - 66M | 0.42s - 94M | 0.75s - 155M gain | 0% - 6% | 23% - 41% | 43% - 50% | 41% - 56% | 40% - 57% | 45% - 58% clang-3.8.0: Size = | 10 | 50 | 100 | 200 | 300 | 500 ------ | ----------- | ----------- | ----------- | ----------- | ----------- | ------------ before | 0.08s - 40M | 0.13s - 44M | 0.19s - 48M | 0.34s - 63M | 0.52s - 81M | 0.98s - 129M after | 0.08s - 40M | 0.13s - 44M | 0.20s - 49M | 0.34s - 62M | 0.51s - 80M | 0.95s - 128M gain | 0% - -1% | 0% - 0% | -5% - -1% | 0% - 0% | 1% - 0% | 3% - 1% ```cpp using list = brigand::sort< brigand::transform< brigand::range<int, 0, SIZE>, brigand::bind<brigand::modulo, brigand::_1, std::integral_constant<int, 40>> > >; ``` gcc-5.4.0: Size = | 10 | 50 | 100 | 200 | 300 | 500 ------ | ----------- | ----------- | ------------ | ------------ | ------------ | ------------ before | 0.07s - 27M | 0.22s - 81M | 0.53s - 177M | 1.66s - 469M | 3.02s - 789M | 5.89s - 1406M after | 0.07s - 21M | 0.13s - 38M | 0.28s - 69M | 0.86s - 175M | 1.78s - 298M | 3.63s - 559M gain | 0% - 21% | 40% - 53% | 47% - 61% | 48% - 62% | 41% - 62% | 38% - 60% clang-3.8.0: Size = | 10 | 50 | 100 | 200 | 300 | 500 ------ | ----------- | ----------- | ----------- | ------------ | ------------ | ------------ before | 0.10s - 41M | 0.17s - 47M | 0.33s - 60M | 0.96s - 127M | 1.76s - 217M | 3.83s - 449M after | 0.10s - 41M | 0.16s - 46M | 0.32s - 59M | 0.92s - 124M | 1.69s - 214M | 3.58s - 443M gain | 0% - 0% | 5% - 0% | 3% - 2% | 4% - 1% | 3% - 1% | 6% - 1% ```cpp using list = brigand::sort<brigand::append< brigand::range<int, SIZE/2, SIZE>, brigand::range<int, 0, SIZE/2> >>; ``` gcc-5.4.0: Size = | 10 | 50 | 100 | 200 | 300 | 500 ------ | ----------- | ----------- | ------------ | ------------ | ------------ | ------------ before | 0.07s - 25M | 0.22s - 81M | 0.46s - 158M | 1.11s - 328M | 1.86s - 534M | 3.38s - 1903M after | 0.05s - 20M | 0.13s - 36M | 0.23s - 59M | 0.52s - 116M | 0.96s - 195M | 1.98s - 332M gain | 28% - 17% | 40% - 54% | 50% - 62% | 53% - 64% | 48% - 63% | 41% - 63% clang-3.8.0: Size = | 10 | 50 | 100 | 200 | 300 | 500 ------ | ----------- | ----------- | ----------- | ----------- | ------------ | ------------ before | 0.09s - 40M | 0.16s - 46M | 0.28s - 55M | 0.61s - 86M | 1.13s - 138M | 2.02s - 245M after | 0.09s - 41M | 0.16s - 46M | 0.27s - 55M | 0.58s - 85M | 1.06s - 137M | 1.97s - 242M gain | 0% - -1% | 0% - 0% | 3% - 0% | 4% - 0% | 6% - 0% | 2% - 1%
```cpp using list = brigand::sort<brigand::range<int, 0, SIZE>>; ``` gcc-5.4.0: Size = | 10 | 50 | 100 | 200 | 300 | 500 ------ | ----------- | ----------- | ----------- | ------------ | ------------ | ------------ before | 0.05s - 21M | 0.12s - 34M | 0.23s - 56M | 0.58s - 125M | 1.20s - 233M | 2.45s - 393M after | 0.06s - 21M | 0.12s - 34M | 0.23s - 56M | 0.58s - 125M | 1.22s - 242M | 2.03s - 351M gain | -20% - -1% | 0% - 0% | 0% - 0% | 0% - 0% | -1% - -3% | 17% - 10% clang-3.8.0: Size = | 10 | 50 | 100 | 200 | 300 | 500 ------ | ----------- | ----------- | ----------- | ----------- | ------------ | ------------ before | 0.09s - 41M | 0.15s - 45M | 0.25s - 54M | 0.64s - 94M | 1.32s - 178M | 2.42s - 317M after | 0.10s - 41M | 0.15s - 46M | 0.26s - 54M | 0.64s - 94M | 1.36s - 176M | 1.95s - 236M gain | -11% - 0% | 0% - 0% | -4% - 0% | 0% - 0% | -3% - 1% | 19% - 25% ```cpp using list = brigand::sort<brigand::reverse_range<int, SIZE, 0>>; ``` gcc-5.4.0: Size = | 10 | 50 | 100 | 200 | 300 | 500 ------ | ----------- | ----------- | ----------- | ----------- | ----------- | ------------ before | 0.05s - 19M | 0.10s - 29M | 0.14s - 40M | 0.27s - 66M | 0.42s - 94M | 0.75s - 155M after | 0.06s - 20M | 0.09s - 29M | 0.15s - 41M | 0.27s - 66M | 0.42s - 94M | 0.76s - 167M gain | -20% - -1% | 10% - -1% | -7% - 0% | 0% - 0% | 0% - 0% | -1% - -7% clang-3.8.0: Size = | 10 | 50 | 100 | 200 | 300 | 500 ------ | ----------- | ----------- | ----------- | ----------- | ----------- | ------------ before | 0.08s - 40M | 0.13s - 44M | 0.20s - 49M | 0.34s - 62M | 0.51s - 80M | 0.95s - 128M after | 0.09s - 41M | 0.13s - 44M | 0.19s - 49M | 0.34s - 63M | 0.49s - 78M | 0.89s - 118M gain | -12% - -1% | 0% - 0% | 5% - 0% | 0% - 0% | 3% - 3% | 6% - 7% ```cpp using list = brigand::sort< brigand::transform< brigand::range<int, 0, SIZE>, brigand::bind<brigand::modulo, brigand::_1, std::integral_constant<int, 40>> > >; ``` gcc-5.4.0: Size = | 10 | 50 | 100 | 200 | 300 | 500 ------ | ----------- | ----------- | ----------- | ------------ | ------------ | ------------ before | 0.07s - 21M | 0.13s - 38M | 0.28s - 69M | 0.86s - 175M | 1.78s - 298M | 3.63s - 559M after | 0.06s - 22M | 0.13s - 38M | 0.29s - 69M | 0.87s - 175M | 1.44s - 278M | 2.66s - 459M gain | 14% - -1% | 0% - 0% | -3% - 0% | -1% - 0% | 19% - 6% | 26% - 17% clang-3.8.0: Size = | 10 | 50 | 100 | 200 | 300 | 500 ------ | ----------- | ----------- | ----------- | ------------ | ------------ | ------------ before | 0.10s - 41M | 0.16s - 46M | 0.32s - 59M | 0.92s - 124M | 1.69s - 214M | 3.58s - 443M after | 0.11s - 41M | 0.17s - 47M | 0.32s - 60M | 0.93s - 124M | 1.51s - 191M | 2.50s - 288M gain | -9% - 0% | -6% - 0% | 0% - -1% | -1% - 0% | 10% - 10% | 30% - 35% ```cpp using list = brigand::sort<brigand::append< brigand::range<int, SIZE/2, SIZE>, brigand::range<int, 0, SIZE/2> >>; ``` gcc-5.4.0: Size = | 10 | 50 | 100 | 200 | 300 | 500 ------ | ----------- | ----------- | ----------- | ------------ | ------------ | ------------ before | 0.05s - 20M | 0.13s - 36M | 0.23s - 59M | 0.52s - 116M | 0.96s - 195M | 1.98s - 332M after | 0.06s - 21M | 0.13s - 37M | 0.24s - 60M | 0.53s - 116M | 0.91s - 191M | 1.85s - 325M gain | -20% - -1% | 0% - -1% | -4% - 0% | -1% - 0% | 5% - 2% | 6% - 2% clang-3.8.0: Size = | 10 | 50 | 100 | 200 | 300 | 500 ------ | ----------- | ----------- | ----------- | ----------- | ------------ | ------------ before | 0.09s - 41M | 0.16s - 46M | 0.27s - 55M | 0.58s - 85M | 1.06s - 137M | 1.97s - 242M after | 0.10s - 41M | 0.16s - 46M | 0.28s - 55M | 0.58s - 85M | 1.00s - 127M | 1.76s - 212M gain | -11% - 0% | 0% - -1% | -3% - 0% | 0% - 0% | 5% - 7% | 10% - 12%
```cpp using list = brigand::sort<brigand::range<int, 0, SIZE>>; ``` gcc-5.4.0: Size = | 10 | 50 | 100 | 200 | 300 | 500 ------ | ----------- | ----------- | ----------- | ------------ | ------------ | ------------ before | 0.06s - 21M | 0.12s - 34M | 0.23s - 56M | 0.58s - 125M | 1.22s - 242M | 2.03s - 351M after | 0.06s - 21M | 0.10s - 31M | 0.18s - 50M | 0.42s - 109M | 0.72s - 178M | 1.40s - 289M gain | 0% - 0% | 16% - 9% | 21% - 10% | 27% - 12% | 40% - 26% | 31% - 17% clang-3.8.0: Size = | 10 | 50 | 100 | 200 | 300 | 500 ------ | ----------- | ----------- | ----------- | ----------- | ------------ | ------------ before | 0.10s - 41M | 0.15s - 46M | 0.26s - 54M | 0.64s - 94M | 1.36s - 176M | 1.95s - 236M after | 0.10s - 41M | 0.14s - 45M | 0.23s - 53M | 0.53s - 80M | 0.88s - 114M | 1.46s - 166M gain | 0% - 0% | 6% - 0% | 11% - 1% | 17% - 15% | 35% - 34% | 25% - 29% ```cpp using list = brigand::sort<brigand::reverse_range<int, SIZE, 0>>; ``` gcc-5.4.0: Size = | 10 | 50 | 100 | 200 | 300 | 500 ------ | ----------- | ----------- | ----------- | ----------- | ------------ | ------------ before | 0.06s - 20M | 0.09s - 29M | 0.15s - 41M | 0.27s - 66M | 0.42s - 94M | 0.76s - 167M after | 0.05s - 20M | 0.10s - 31M | 0.16s - 45M | 0.29s - 75M | 0.42s - 109M | 0.78s - 192M gain | 16% - -4% | -11% - -6% | -6% - 10% | -7% - 14% | 0% - -16% | -2% - -14% clang-3.8.0: Size = | 10 | 50 | 100 | 200 | 300 | 500 ------ | ----------- | ----------- | ----------- | ----------- | ----------- | ------------ before | 0.09s - 41M | 0.13s - 44M | 0.19s - 49M | 0.34s - 63M | 0.49s - 78M | 0.89s - 118M after | 0.09s - 41M | 0.14s - 45M | 0.21s - 51M | 0.36s - 64M | 0.54s - 80M | 0.96s - 121M gain | 0% - 0% | -7% - -2% | -10% - -3% | -5% - -2% | -10% - -3% | -7% - -2% ```cpp using list = brigand::sort< brigand::transform< brigand::range<int, 0, SIZE>, brigand::bind<brigand::modulo, brigand::_1, std::integral_constant<int, 40>> > >; ``` gcc-5.4.0: Size = | 10 | 50 | 100 | 200 | 300 | 500 ------ | ----------- | ----------- | ----------- | ------------ | ------------ | ------------ before | 0.06s - 22M | 0.13s - 38M | 0.29s - 69M | 0.87s - 175M | 1.44s - 278M | 2.66s - 459M after | 0.06s - 22M | 0.11s - 36M | 0.23s - 63M | 0.59s - 141M | 1.01s - 238M | 2.06s - 411M gain | 0% - 0% | 15% - 5% | 20% - 7% | 32% - 19% | 29% - 14% | 22% - 10% clang-3.8.0: Size = | 10 | 50 | 100 | 200 | 300 | 500 ------ | ----------- | ----------- | ----------- | ------------ | ------------ | ------------ before | 0.11s - 41M | 0.17s - 47M | 0.32s - 60M | 0.93s - 124M | 1.51s - 191M | 2.50s - 288M after | 0.10s - 42M | 0.17s - 47M | 0.29s - 59M | 0.70s - 99M | 1.24s - 160M | 2.19s - 256M gain | 9% - -1% | 0% - 0% | 9% - 0% | 24% - 20% | 17% - 16% | 12% - 10% ```cpp using list = brigand::sort<brigand::append< brigand::range<int, SIZE/2, SIZE>, brigand::range<int, 0, SIZE/2> >>; ``` gcc-5.4.0: Size = | 10 | 50 | 100 | 200 | 300 | 500 ------ | ----------- | ----------- | ----------- | ------------ | ------------ | ------------ before | 0.06s - 21M | 0.13s - 37M | 0.24s - 60M | 0.53s - 116M | 0.91s - 191M | 1.85s - 325M after | 0.06s - 21M | 0.11s - 34M | 0.19s - 51M | 0.37s - 95M | 0.69s - 168M | 1.39s - 288M gain | 0% - 0% | 15% - 7% | 20% - 14% | 30% - 18% | 24% - 11% | 24% - 11% clang-3.8.0: Size = | 10 | 50 | 100 | 200 | 300 | 500 ------ | ----------- | ----------- | ----------- | ----------- | ------------ | ------------ before | 0.10s - 41M | 0.16s - 46M | 0.28s - 55M | 0.58s - 85M | 1.00s - 127M | 1.76s - 212M after | 0.09s - 41M | 0.16s - 46M | 0.24s - 54M | 0.46s - 72M | 0.86s - 118M | 1.45s - 167M gain | 10% - 0% | 0% - 0% | 14% - 3% | 20% - 14% | 14% - 7% | 17% - 21%
Nice job! I think we can optimize even further by using the "universal fast track approach". still 500 elements in just over a second is amazing! |
} | ||
|
||
template<class Seq1, class Seq2, class Comp = less<_1,_2>> | ||
using merge = append<clear<Seq1>, typename detail::merge_impl<clear<Seq1>, wrap<Seq1, list>, wrap<Seq2, list>, Comp>::type>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't you mean detail::merge_impl<list<>, wrap<Seq1, list>, wrap<Seq2, list>, Comp>::type
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rogue, he escaped.
Probably. I tried some tricks, but without results. I think tried 1 or 2 other things. |
I just test again with the "universal fast track" by applying it directly on template <template<typename,typename> class F, typename T, typename U>
struct apply<F<_1,_2>, list<T, U>> : F<T, U>
{
};
template <template<typename,typename> class F, typename T, typename U>
struct apply<F<_2,_1>, list<T, U>> : F<U, T>
{
}; gcc: ~+20% |
Yes under one second, the race is on ;) for kvasir I need 1000 elements to not crash and not be more than the default max instantiation depth |
Is this sort stable? |
I think #208 is the last bug. I have been hammering it. |
No, but it could. In the meantime. template<class L, class Comp> using stable_sort
= sort<L, not_<bind<apply, pin<Comp>, _2, _1>>>; |
@ldionne do you have any specific use case in mind for a stable sort? I'm curious. |
It's just that Hana's sort is documented as being stable, and I would love to steal Brigand's implementation. |
sounds like we need to make it stable |
Well, if anything, it would be wiser to provide a |
Got it, thanks. |
|
gcc-5.4.0:
clang-3.8.0:
gcc-5.4.0:
clang-3.8.0:
gcc-5.4.0:
clang-3.8.0:
gcc-5.4.0:
clang-3.8.0: