Skip to content

Conversation

halx99
Copy link
Contributor

@halx99 halx99 commented Jul 15, 2016

No description provided.

@minggo
Copy link
Contributor

minggo commented Jul 15, 2016

Why switch to sort again? Does it have better performance? How much percent it improves? Thanks.

@halx99
Copy link
Contributor Author

halx99 commented Jul 15, 2016

The sort performance will improve 50%~100%

auto node = _children.at(i);

if (node && node->_localZOrder < 0)
if (node && node->getLocalZOrder() < 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_loacalZOrder is defined as unsigned long long in this PR, then node->getLocalZOrder() < 0 will be false for ever.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

26f6w 1g 51 1bfgxlu r6h

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but it is a unsigned long long, why it will less than 0?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, sorry, here is local z order, not s_globalOrderOfArrival.

@minggo
Copy link
Contributor

minggo commented Jul 18, 2016

The sort performance will improve 50%~100%

Can you provide the test case? Thanks.

@halx99
Copy link
Contributor Author

halx99 commented Jul 18, 2016

test result:
n6a3w d8z g 6l7i9i9k by

test code:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <vector>
#include <time.h>

int main(int, char**)
{
    std::vector<std::pair<int, int>*> vec2;

    for (auto i = 0; i < 1000000; ++i)
        vec2.push_back(new std::pair<int, int>(2, i + 1));

    clock_t start = 0;

    for (int i = 0; i < 10; ++i) {
        start = clock();
        std::stable_sort(vec2.begin(), vec2.end(), [](const std::pair<int, int>* l, const std::pair<int, int>* r) {
            return l->first < r->first;
        });
        printf("std::stable_sort, test round:%d, %lf seconds used.\n", i + 1, (clock() - start) / (double)CLOCKS_PER_SEC);
    }

    for (int i = 0; i < 10; ++i) {
        start = clock();
        std::sort(vec2.begin(), vec2.end(), [](const std::pair<int, int>* l, const std::pair<int, int>* r) {
            return l->first < r->first || (l->first == r->first && l->second < r->second);
        });
        printf("std::sort, no optimize orderOfArrival storage, original implement, test round:%d, %lf seconds used.\n", i + 1, (clock() - start) / (double)CLOCKS_PER_SEC);
    }

    for (int i = 0; i < 10; ++i) {
        start = clock();
        std::sort(vec2.begin(), vec2.end(), [](const std::pair<int, int>* l, const std::pair<int, int>* r) {
            return *(long long*)l < *(long long*)r;
        });
        printf("std::sort, optimize orderOfArrival storage, test round:%d, %lf seconds used.\n", i + 1, (clock() - start) / (double)CLOCKS_PER_SEC);
    }

    system("pause");
    return 0;
}

@halx99 halx99 changed the title #improve node sort performance by std::sort + unsigned long long (_localZOrder) #improve node sort performance by std::sort + long long (_localZOrder) Jul 19, 2016
@minggo
Copy link
Contributor

minggo commented Jul 20, 2016

@halx99 i think this PR will break compatibility, right?

@halx99
Copy link
Contributor Author

halx99 commented Jul 20, 2016

I don't think so, I already chagne stroage to long long, and use bit field for make _localZOrder storage & operation more clearly.

@halx99
Copy link
Contributor Author

halx99 commented Jul 20, 2016

Well, If developer call setOrderOfArrival/getOrderOfArrival manually, they will be affected.

@halx99
Copy link
Contributor Author

halx99 commented Jul 20, 2016

Does need provide setOrderOfArrival/getOrderOfArrival still for compatibility?

@minggo
Copy link
Contributor

minggo commented Jul 20, 2016

Does need provide setOrderOfArrival/getOrderOfArrival still for compatibility?

I don't quite understand, you don't remove these two functions, why is there compatibility issue?

@halx99
Copy link
Contributor Author

halx99 commented Jul 20, 2016

I think no compatibility issue, because 3.12 already remove the two functions

@minggo
Copy link
Contributor

minggo commented Jul 20, 2016

Ok, i will try your test case to check the result. It seems it is valuable if it can improve 50%-100%. @ricardoquesada what's your opinion?

@halx99
Copy link
Contributor Author

halx99 commented Jul 20, 2016

OK

@ricardoquesada
Copy link
Contributor

+1 for improving performance.

But does this patch only improves the performance in 64-bit? if so, what will happen on 32-bit OSs (like Android)?

I think we should run the test on Android 32-bit before merging it.
Regardless of the result, making comparisonNodeLess a friend function looks Ok to me.

{
if (_reorderChildDirty)
{
std::stable_sort(std::begin(_children), std::end(_children), nodeComparisonLess);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you revert from stable sort? Did you refer to why stable was added in the first place?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah nevermind, I see it's all about going back to std::sort :D
I should've read the original post instead of just the commit.

@halx99
Copy link
Contributor Author

halx99 commented Jul 20, 2016

Yes, It's 64 bits, and 32bits test result:
qpzwlz u3 iq6 9j y 0w

@ricardoquesada
Copy link
Contributor

looks good to me then. Thanks for the PR!

*
* @param orderOfArrival The arrival order.
*/
CC_DEPRECATED_ATTRIBUTE void _updateOrderOfArrival(void);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is better to put into protected if it is used internally and its sub classes

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better, but if mark as protected, The ProtectedNode chould access it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ProtectedNode inherits Node, i think there is not problem. And

  • CC_DEPRECATED_ATTRIBUTE is not needed
  • _updateOrderOfArrival -> updateOrderOfArrival
  • remove void

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I already tried mark as protected, but chould't compile with follow error:
1777qi4edz 3 yzi a ce i

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, but please

  • remove CC_DEPRECATED_ATTRIBUTE since it is not deprecated, it is used
  • _updateOrderOfArrival -> updateOrderOfArrival
  • remove void

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I done this.

@minggo
Copy link
Contributor

minggo commented Jul 21, 2016

@halx99 your test case is just for stable_sort and sort, not for cocos2d-x. Because your modify the codes, now in Node::visit(), the logical changed from if (node && node->_localZOrder < 0) to if (node && node->getLocalZOrder() < 0). As you can see, it will invoke function instead of visit value directly. So i think the test case should base on cocos2d-x.

@halx99
Copy link
Contributor Author

halx99 commented Jul 21, 2016

There we can use node->_localZOrder->detail.z < 0 instead.

@halx99
Copy link
Contributor Author

halx99 commented Jul 21, 2016

Actual, I think the compilier will optimize the code for release mode normally.

@minggo
Copy link
Contributor

minggo commented Jul 21, 2016

Yep, i think so. What i mean is that, have you tested it with cocos2d-x? I think we need to test it in cocos2d-x.

@halx99
Copy link
Contributor Author

halx99 commented Jul 21, 2016

It not easy to test it in cocos2d-x, because it need large numbers of entity for distinguish the test result.

@halx99
Copy link
Contributor Author

halx99 commented Jul 26, 2016

It seems the optimization has not effect. So far, our all test result is 32bits program, The optimize maybe will effect on 64bits program, Let's check it.

@halx99
Copy link
Contributor Author

halx99 commented Jul 26, 2016

Your last test result is approach me, chould upload your last apk let me try on my device firstly. You can upload to baidu cloud and share to me.

@minggo
Copy link
Contributor

minggo commented Jul 26, 2016

@halx99 i think it is better you build it yourself. It is easy, just fetch my branch and build it.

@halx99
Copy link
Contributor Author

halx99 commented Jul 26, 2016

OK, let me do it.

@halx99
Copy link
Contributor Author

halx99 commented Jul 26, 2016

The test result:

D   07-26 16:31:39.604  875 875  cpp-empty-test test program is 32 bits!
D   07-26 16:31:39.805  875 875  cpp-empty-test std::stable_sort, test round:1, 0.157418 seconds used.
D   07-26 16:31:39.963  875 875  cpp-empty-test std::stable_sort, test round:2, 0.157180 seconds used.
D   07-26 16:31:40.142  875 875  cpp-empty-test std::stable_sort, test round:3, 0.164037 seconds used.
D   07-26 16:31:40.294  875 875  cpp-empty-test std::stable_sort, test round:4, 0.151566 seconds used.
D   07-26 16:31:40.443  875 875  cpp-empty-test std::stable_sort, test round:5, 0.148551 seconds used.
D   07-26 16:31:40.592  875 875  cpp-empty-test std::stable_sort, test round:6, 0.149345 seconds used.
D   07-26 16:31:40.741  875 875  cpp-empty-test std::stable_sort, test round:7, 0.149152 seconds used.
D   07-26 16:31:40.891  875 875  cpp-empty-test std::stable_sort, test round:8, 0.149006 seconds used.
D   07-26 16:31:41.040  875 875  cpp-empty-test std::stable_sort, test round:9, 0.149325 seconds used.
D   07-26 16:31:41.194  875 875  cpp-empty-test std::stable_sort, test round:10, 0.151338 seconds used.
D   07-26 16:31:41.279  875 875  cpp-empty-test std::sort(order not stable), test round:1, 0.083925 seconds used.
D   07-26 16:31:41.369  875 875  cpp-empty-test std::sort(order not stable), test round:2, 0.085925 seconds used.
D   07-26 16:31:41.455  875 875  cpp-empty-test std::sort(order not stable), test round:3, 0.084190 seconds used.
D   07-26 16:31:41.587  875 875  cpp-empty-test std::sort(order not stable), test round:4, 0.105795 seconds used.
D   07-26 16:31:41.724  875 875  cpp-empty-test std::sort(order not stable), test round:5, 0.118931 seconds used.
D   07-26 16:31:41.867  875 875  cpp-empty-test std::sort(order not stable), test round:6, 0.126338 seconds used.
D   07-26 16:31:41.968  875 875  cpp-empty-test std::sort(order not stable), test round:7, 0.090182 seconds used.
D   07-26 16:31:42.056  875 875  cpp-empty-test std::sort(order not stable), test round:8, 0.084774 seconds used.
D   07-26 16:31:42.140  875 875  cpp-empty-test std::sort(order not stable), test round:9, 0.083931 seconds used.
D   07-26 16:31:42.223  875 875  cpp-empty-test std::sort(order not stable), test round:10, 0.082346 seconds used.
D   07-26 16:31:42.325  875 875  cpp-empty-test std::sort, no optimize orderOfArrival storage, original implement, test round:1, 0.100184 seconds used.
D   07-26 16:31:42.421  875 875  cpp-empty-test std::sort, no optimize orderOfArrival storage, original implement, test round:2, 0.094831 seconds used.
D   07-26 16:31:42.517  875 875  cpp-empty-test std::sort, no optimize orderOfArrival storage, original implement, test round:3, 0.094685 seconds used.
D   07-26 16:31:42.620  875 875  cpp-empty-test std::sort, no optimize orderOfArrival storage, original implement, test round:4, 0.096047 seconds used.
D   07-26 16:31:42.716  875 875  cpp-empty-test std::sort, no optimize orderOfArrival storage, original implement, test round:5, 0.094275 seconds used.
D   07-26 16:31:42.811  875 875  cpp-empty-test std::sort, no optimize orderOfArrival storage, original implement, test round:6, 0.094292 seconds used.
D   07-26 16:31:42.905  875 875  cpp-empty-test std::sort, no optimize orderOfArrival storage, original implement, test round:7, 0.092691 seconds used.
D   07-26 16:31:43.002  875 875  cpp-empty-test std::sort, no optimize orderOfArrival storage, original implement, test round:8, 0.094817 seconds used.
D   07-26 16:31:43.101  875 875  cpp-empty-test std::sort, no optimize orderOfArrival storage, original implement, test round:9, 0.093167 seconds used.
D   07-26 16:31:43.198  875 875  cpp-empty-test std::sort, no optimize orderOfArrival storage, original implement, test round:10, 0.094367 seconds used.
D   07-26 16:31:43.301  875 875  cpp-empty-test std::sort, optimize orderOfArrival storage, test round:1, 0.101517 seconds used.
D   07-26 16:31:43.404  875 875  cpp-empty-test std::sort, optimize orderOfArrival storage, test round:2, 0.101305 seconds used.
D   07-26 16:31:43.511  875 875  cpp-empty-test std::sort, optimize orderOfArrival storage, test round:3, 0.101890 seconds used.
D   07-26 16:31:43.622  875 875  cpp-empty-test std::sort, optimize orderOfArrival storage, test round:4, 0.102170 seconds used.
D   07-26 16:31:43.783  875 875  cpp-empty-test std::sort, optimize orderOfArrival storage, test round:5, 0.160289 seconds used.
D   07-26 16:31:43.946  875 875  cpp-empty-test std::sort, optimize orderOfArrival storage, test round:6, 0.161821 seconds used.
D   07-26 16:31:44.117  875 875  cpp-empty-test std::sort, optimize orderOfArrival storage, test round:7, 0.166112 seconds used.
D   07-26 16:31:44.280  875 875  cpp-empty-test std::sort, optimize orderOfArrival storage, test round:8, 0.161053 seconds used.
D   07-26 16:31:44.446  875 875  cpp-empty-test std::sort, optimize orderOfArrival storage, test round:9, 0.163926 seconds used.
D   07-26 16:31:44.615  875 875  cpp-empty-test std::sort, optimize orderOfArrival storage, test round:10, 0.162233 seconds used.

My environment:
NDK r10e
Windows 10
Xiaomi4

@halx99
Copy link
Contributor Author

halx99 commented Jul 26, 2016

@minggo Hi, I move the my empty test project test code from HelloWorldScene::init to same as you( before AppDelegate *pAppDelegate = new AppDelegate();) and test again, and the result is same with yours
The optimize speed is slowest.

D   07-26 16:44:51.926  5568    5568     main       std::sort, optimize orderOfArrival storage, test round:2, 0.313969 seconds used.
D   07-26 16:44:46.314  5568    5568     main       cocos_android_app_init
D   07-26 16:44:46.314  5568    5568     main       test program is 32 bits!
D   07-26 16:44:46.606  5568    5568     main       std::stable_sort, test round:1, 0.244510 seconds used.
D   07-26 16:44:46.858  5568    5568     main       std::stable_sort, test round:2, 0.243155 seconds used.
D   07-26 16:44:47.095  5568    5568     main       std::stable_sort, test round:3, 0.236453 seconds used.
D   07-26 16:44:47.331  5568    5568     main       std::stable_sort, test round:4, 0.236040 seconds used.
D   07-26 16:44:47.568  5568    5568     main       std::stable_sort, test round:5, 0.236649 seconds used.
D   07-26 16:44:47.806  5568    5568     main       std::stable_sort, test round:6, 0.237646 seconds used.
D   07-26 16:44:48.048  5568    5568     main       std::stable_sort, test round:7, 0.239096 seconds used.
D   07-26 16:44:48.370  5568    5568     main       std::stable_sort, test round:8, 0.279833 seconds used.
D   07-26 16:44:48.714  5568    5568     main       std::stable_sort, test round:9, 0.299102 seconds used.
D   07-26 16:44:49.011  5568    5568     main       std::stable_sort, test round:10, 0.293240 seconds used.
D   07-26 16:44:49.122  5568    5568     main       std::sort(order not stable), test round:1, 0.109801 seconds used.
D   07-26 16:44:49.247  5568    5568     main       std::sort(order not stable), test round:2, 0.121459 seconds used.
D   07-26 16:44:49.333  5568    5568     main       std::sort(order not stable), test round:3, 0.083982 seconds used.
D   07-26 16:44:49.419  5568    5568     main       std::sort(order not stable), test round:4, 0.083191 seconds used.
D   07-26 16:44:49.519  5568    5568     main       std::sort(order not stable), test round:5, 0.093139 seconds used.
D   07-26 16:44:49.630  5568    5568     main       std::sort(order not stable), test round:6, 0.108338 seconds used.
D   07-26 16:44:49.759  5568    5568     main       std::sort(order not stable), test round:7, 0.126840 seconds used.
D   07-26 16:44:49.887  5568    5568     main       std::sort(order not stable), test round:8, 0.126673 seconds used.
D   07-26 16:44:50.016  5568    5568     main       std::sort(order not stable), test round:9, 0.113890 seconds used.
D   07-26 16:44:50.117  5568    5568     main       std::sort(order not stable), test round:10, 0.097936 seconds used.
D   07-26 16:44:50.272  5568    5568     main       std::sort, no optimize orderOfArrival storage, original implement, test round:1, 0.148423 seconds used.
D   07-26 16:44:50.396  5568    5568     main       std::sort, no optimize orderOfArrival storage, original implement, test round:2, 0.119352 seconds used.
D   07-26 16:44:50.532  5568    5568     main       std::sort, no optimize orderOfArrival storage, original implement, test round:3, 0.131537 seconds used.
D   07-26 16:44:50.641  5568    5568     main       std::sort, no optimize orderOfArrival storage, original implement, test round:4, 0.107349 seconds used.
D   07-26 16:44:50.750  5568    5568     main       std::sort, no optimize orderOfArrival storage, original implement, test round:5, 0.107055 seconds used.
D   07-26 16:44:50.859  5568    5568     main       std::sort, no optimize orderOfArrival storage, original implement, test round:6, 0.107075 seconds used.
D   07-26 16:44:50.968  5568    5568     main       std::sort, no optimize orderOfArrival storage, original implement, test round:7, 0.108231 seconds used.
D   07-26 16:44:51.078  5568    5568     main       std::sort, no optimize orderOfArrival storage, original implement, test round:8, 0.107814 seconds used.
D   07-26 16:44:51.188  5568    5568     main       std::sort, no optimize orderOfArrival storage, original implement, test round:9, 0.108568 seconds used.
D   07-26 16:44:51.297  5568    5568     main       std::sort, no optimize orderOfArrival storage, original implement, test round:10, 0.107550 seconds used.
D   07-26 16:44:51.608  5568    5568     main       std::sort, optimize orderOfArrival storage, test round:1, 0.304942 seconds used.
D   07-26 16:44:52.239  5568    5568     main       std::sort, optimize orderOfArrival storage, test round:3, 0.308553 seconds used.
D   07-26 16:44:52.551  5568    5568     main       std::sort, optimize orderOfArrival storage, test round:4, 0.307756 seconds used.
D   07-26 16:44:52.859  5568    5568     main       std::sort, optimize orderOfArrival storage, test round:5, 0.303378 seconds used.
D   07-26 16:44:53.171  5568    5568     main       std::sort, optimize orderOfArrival storage, test round:6, 0.307443 seconds used.
D   07-26 16:44:53.490  5568    5568     main       std::sort, optimize orderOfArrival storage, test round:7, 0.307883 seconds used.
D   07-26 16:44:53.799  5568    5568     main       std::sort, optimize orderOfArrival storage, test round:8, 0.305909 seconds used.
D   07-26 16:44:54.106  5568    5568     main       std::sort, optimize orderOfArrival storage, test round:9, 0.304631 seconds used.
D   07-26 16:44:54.511  5568    5568     main       std::sort, optimize orderOfArrival storage, test round:10, 0.396338 seconds used.

@halx99
Copy link
Contributor Author

halx99 commented Jul 26, 2016

Let me test and test.

@halx99
Copy link
Contributor Author

halx99 commented Jul 26, 2016

I test many times: your project result is all same:

D   07-26 17:08:16.551  15708   15763    cocos2d-x debug info   std::sort, optimize orderOfArrival storage, test round:9, 0.101433 seconds used.
D   07-26 17:08:06.352  15708   15708    cocos2d-x debug info   cocos_android_app_init
D   07-26 17:08:06.356  15708   15708    cocos2d-x debug info   test program is 32 bits!
D   07-26 17:08:06.568  15708   15708    cocos2d-x debug info   std::stable_sort, test round:1, 0.162571 seconds used.
D   07-26 17:08:06.714  15708   15708    cocos2d-x debug info   std::stable_sort, test round:2, 0.141555 seconds used.
D   07-26 17:08:06.868  15708   15708    cocos2d-x debug info   std::stable_sort, test round:3, 0.147353 seconds used.
D   07-26 17:08:07.019  15708   15708    cocos2d-x debug info   std::stable_sort, test round:4, 0.142910 seconds used.
D   07-26 17:08:07.159  15708   15708    cocos2d-x debug info   std::stable_sort, test round:5, 0.137765 seconds used.
D   07-26 17:08:07.300  15708   15708    cocos2d-x debug info   std::stable_sort, test round:6, 0.137579 seconds used.
D   07-26 17:08:07.438  15708   15708    cocos2d-x debug info   std::stable_sort, test round:7, 0.138239 seconds used.
D   07-26 17:08:07.577  15708   15708    cocos2d-x debug info   std::stable_sort, test round:8, 0.138418 seconds used.
D   07-26 17:08:07.717  15708   15708    cocos2d-x debug info   std::stable_sort, test round:9, 0.138967 seconds used.
D   07-26 17:08:07.860  15708   15708    cocos2d-x debug info   std::stable_sort, test round:10, 0.140781 seconds used.
D   07-26 17:08:07.942  15708   15708    cocos2d-x debug info   std::sort(order not stable), test round:1, 0.080945 seconds used.
D   07-26 17:08:08.024  15708   15708    cocos2d-x debug info   std::sort(order not stable), test round:2, 0.080248 seconds used.
D   07-26 17:08:08.129  15708   15708    cocos2d-x debug info   std::sort(order not stable), test round:3, 0.094508 seconds used.
D   07-26 17:08:08.248  15708   15708    cocos2d-x debug info   std::sort(order not stable), test round:4, 0.092332 seconds used.
D   07-26 17:08:08.360  15708   15708    cocos2d-x debug info   std::sort(order not stable), test round:5, 0.091274 seconds used.
D   07-26 17:08:08.527  15708   15708    cocos2d-x debug info   std::sort(order not stable), test round:6, 0.153132 seconds used.
D   07-26 17:08:08.650  15708   15708    cocos2d-x debug info   std::sort(order not stable), test round:7, 0.101315 seconds used.
D   07-26 17:08:08.731  15708   15708    cocos2d-x debug info   std::sort(order not stable), test round:8, 0.081324 seconds used.
D   07-26 17:08:08.814  15708   15708    cocos2d-x debug info   std::sort(order not stable), test round:9, 0.081278 seconds used.
D   07-26 17:08:08.898  15708   15708    cocos2d-x debug info   std::sort(order not stable), test round:10, 0.082725 seconds used.
D   07-26 17:08:08.999  15708   15708    cocos2d-x debug info   std::sort, no optimize orderOfArrival storage, original implement, test round:1, 0.099226 seconds used.
D   07-26 17:08:09.093  15708   15708    cocos2d-x debug info   std::sort, no optimize orderOfArrival storage, original implement, test round:2, 0.093093 seconds used.
D   07-26 17:08:09.191  15708   15708    cocos2d-x debug info   std::sort, no optimize orderOfArrival storage, original implement, test round:3, 0.092584 seconds used.
D   07-26 17:08:09.286  15708   15708    cocos2d-x debug info   std::sort, no optimize orderOfArrival storage, original implement, test round:4, 0.092923 seconds used.
D   07-26 17:08:09.386  15708   15708    cocos2d-x debug info   std::sort, no optimize orderOfArrival storage, original implement, test round:5, 0.094955 seconds used.
D   07-26 17:08:09.482  15708   15708    cocos2d-x debug info   std::sort, no optimize orderOfArrival storage, original implement, test round:6, 0.093370 seconds used.
D   07-26 17:08:09.608  15708   15708    cocos2d-x debug info   std::sort, no optimize orderOfArrival storage, original implement, test round:7, 0.119424 seconds used.
D   07-26 17:08:09.704  15708   15708    cocos2d-x debug info   std::sort, no optimize orderOfArrival storage, original implement, test round:8, 0.093170 seconds used.
D   07-26 17:08:09.818  15708   15708    cocos2d-x debug info   std::sort, no optimize orderOfArrival storage, original implement, test round:9, 0.092825 seconds used.
D   07-26 17:08:09.912  15708   15708    cocos2d-x debug info   std::sort, no optimize orderOfArrival storage, original implement, test round:10, 0.091850 seconds used.
D   07-26 17:08:10.014  15708   15708    cocos2d-x debug info   std::sort, optimize orderOfArrival storage, test round:1, 0.099852 seconds used.
D   07-26 17:08:10.113  15708   15708    cocos2d-x debug info   std::sort, optimize orderOfArrival storage, test round:2, 0.098893 seconds used.
D   07-26 17:08:10.216  15708   15708    cocos2d-x debug info   std::sort, optimize orderOfArrival storage, test round:3, 0.099996 seconds used.
D   07-26 17:08:10.318  15708   15708    cocos2d-x debug info   std::sort, optimize orderOfArrival storage, test round:4, 0.098975 seconds used.
D   07-26 17:08:10.450  15708   15708    cocos2d-x debug info   std::sort, optimize orderOfArrival storage, test round:5, 0.123916 seconds used.
D   07-26 17:08:10.643  15708   15708    cocos2d-x debug info   std::sort, optimize orderOfArrival storage, test round:6, 0.185309 seconds used.
D   07-26 17:08:10.830  15708   15708    cocos2d-x debug info   std::sort, optimize orderOfArrival storage, test round:7, 0.183674 seconds used.
D   07-26 17:08:11.015  15708   15708    cocos2d-x debug info   std::sort, optimize orderOfArrival storage, test round:8, 0.183091 seconds used.
D   07-26 17:08:11.201  15708   15708    cocos2d-x debug info   std::sort, optimize orderOfArrival storage, test round:9, 0.183865 seconds used.
D   07-26 17:08:11.387  15708   15708    cocos2d-x debug info   std::sort, optimize orderOfArrival storage, test round:10, 0.183219 seconds used.
D   07-26 17:08:12.058  15708   15763    cocos2d-x debug info   test program is 32 bits!
D   07-26 17:08:12.271  15708   15763    cocos2d-x debug info   std::stable_sort, test round:1, 0.165542 seconds used.
D   07-26 17:08:12.438  15708   15763    cocos2d-x debug info   std::stable_sort, test round:2, 0.163716 seconds used.
D   07-26 17:08:12.603  15708   15763    cocos2d-x debug info   std::stable_sort, test round:3, 0.161999 seconds used.
D   07-26 17:08:12.770  15708   15763    cocos2d-x debug info   std::stable_sort, test round:4, 0.163330 seconds used.
D   07-26 17:08:12.934  15708   15763    cocos2d-x debug info   std::stable_sort, test round:5, 0.161556 seconds used.
D   07-26 17:08:13.100  15708   15763    cocos2d-x debug info   std::stable_sort, test round:6, 0.162888 seconds used.
D   07-26 17:08:13.265  15708   15763    cocos2d-x debug info   std::stable_sort, test round:7, 0.162346 seconds used.
D   07-26 17:08:13.431  15708   15763    cocos2d-x debug info   std::stable_sort, test round:8, 0.163068 seconds used.
D   07-26 17:08:13.595  15708   15763    cocos2d-x debug info   std::stable_sort, test round:9, 0.161738 seconds used.
D   07-26 17:08:13.759  15708   15763    cocos2d-x debug info   std::stable_sort, test round:10, 0.161710 seconds used.
D   07-26 17:08:13.844  15708   15763    cocos2d-x debug info   std::sort(order not stable), test round:1, 0.084358 seconds used.
D   07-26 17:08:13.929  15708   15763    cocos2d-x debug info   std::sort(order not stable), test round:2, 0.083409 seconds used.
D   07-26 17:08:14.014  15708   15763    cocos2d-x debug info   std::sort(order not stable), test round:3, 0.084071 seconds used.
D   07-26 17:08:14.105  15708   15763    cocos2d-x debug info   std::sort(order not stable), test round:4, 0.083441 seconds used.
D   07-26 17:08:14.191  15708   15763    cocos2d-x debug info   std::sort(order not stable), test round:5, 0.085609 seconds used.
D   07-26 17:08:14.280  15708   15763    cocos2d-x debug info   std::sort(order not stable), test round:6, 0.085369 seconds used.
D   07-26 17:08:14.365  15708   15763    cocos2d-x debug info   std::sort(order not stable), test round:7, 0.083894 seconds used.
D   07-26 17:08:14.452  15708   15763    cocos2d-x debug info   std::sort(order not stable), test round:8, 0.084679 seconds used.
D   07-26 17:08:14.538  15708   15763    cocos2d-x debug info   std::sort(order not stable), test round:9, 0.083909 seconds used.
D   07-26 17:08:14.623  15708   15763    cocos2d-x debug info   std::sort(order not stable), test round:10, 0.084078 seconds used.
D   07-26 17:08:14.725  15708   15763    cocos2d-x debug info   std::sort, no optimize orderOfArrival storage, original implement, test round:1, 0.100704 seconds used.
D   07-26 17:08:14.822  15708   15763    cocos2d-x debug info   std::sort, no optimize orderOfArrival storage, original implement, test round:2, 0.095933 seconds used.
D   07-26 17:08:14.919  15708   15763    cocos2d-x debug info   std::sort, no optimize orderOfArrival storage, original implement, test round:3, 0.095098 seconds used.
D   07-26 17:08:15.016  15708   15763    cocos2d-x debug info   std::sort, no optimize orderOfArrival storage, original implement, test round:4, 0.095580 seconds used.
D   07-26 17:08:15.112  15708   15763    cocos2d-x debug info   std::sort, no optimize orderOfArrival storage, original implement, test round:5, 0.094480 seconds used.
D   07-26 17:08:15.209  15708   15763    cocos2d-x debug info   std::sort, no optimize orderOfArrival storage, original implement, test round:6, 0.095799 seconds used.
D   07-26 17:08:15.329  15708   15763    cocos2d-x debug info   std::sort, no optimize orderOfArrival storage, original implement, test round:7, 0.095028 seconds used.
D   07-26 17:08:15.425  15708   15763    cocos2d-x debug info   std::sort, no optimize orderOfArrival storage, original implement, test round:8, 0.095361 seconds used.
D   07-26 17:08:15.523  15708   15763    cocos2d-x debug info   std::sort, no optimize orderOfArrival storage, original implement, test round:9, 0.093137 seconds used.
D   07-26 17:08:15.617  15708   15763    cocos2d-x debug info   std::sort, no optimize orderOfArrival storage, original implement, test round:10, 0.092899 seconds used.
D   07-26 17:08:15.719  15708   15763    cocos2d-x debug info   std::sort, optimize orderOfArrival storage, test round:1, 0.100985 seconds used.
D   07-26 17:08:15.821  15708   15763    cocos2d-x debug info   std::sort, optimize orderOfArrival storage, test round:2, 0.100110 seconds used.
D   07-26 17:08:15.923  15708   15763    cocos2d-x debug info   std::sort, optimize orderOfArrival storage, test round:3, 0.101611 seconds used.
D   07-26 17:08:16.027  15708   15763    cocos2d-x debug info   std::sort, optimize orderOfArrival storage, test round:4, 0.101269 seconds used.
D   07-26 17:08:16.129  15708   15763    cocos2d-x debug info   std::sort, optimize orderOfArrival storage, test round:5, 0.101269 seconds used.
D   07-26 17:08:16.235  15708   15763    cocos2d-x debug info   std::sort, optimize orderOfArrival storage, test round:6, 0.099576 seconds used.
D   07-26 17:08:16.345  15708   15763    cocos2d-x debug info   std::sort, optimize orderOfArrival storage, test round:7, 0.107319 seconds used.
D   07-26 17:08:16.448  15708   15763    cocos2d-x debug info   std::sort, optimize orderOfArrival storage, test round:8, 0.102024 seconds used.
D   07-26 17:08:16.662  15708   15763    cocos2d-x debug info   std::sort, optimize orderOfArrival storage, test round:10, 0.108624 seconds used.

@minggo
Copy link
Contributor

minggo commented Jul 26, 2016

@halx99 so i think we should

  • replace std::stable_sort with std::sort
  • use the optimization for 64bit and no optimization solution for 32bit

@halx99
Copy link
Contributor Author

halx99 commented Jul 26, 2016

I test many times for my empty project:
The result is:

D   07-26 17:38:32.711  26896   26896    cpp-empty-test test program is 32 bits!
D   07-26 17:38:32.948  26896   26896    cpp-empty-test std::stable_sort, test round:1, 0.186967 seconds used.
D   07-26 17:38:33.134  26896   26896    cpp-empty-test std::stable_sort, test round:2, 0.182021 seconds used.
D   07-26 17:38:33.327  26896   26896    cpp-empty-test std::stable_sort, test round:3, 0.180050 seconds used.
D   07-26 17:38:33.502  26896   26896    cpp-empty-test std::stable_sort, test round:4, 0.174486 seconds used.
D   07-26 17:38:33.678  26896   26896    cpp-empty-test std::stable_sort, test round:5, 0.175075 seconds used.
D   07-26 17:38:33.853  26896   26896    cpp-empty-test std::stable_sort, test round:6, 0.173667 seconds used.
D   07-26 17:38:34.030  26896   26896    cpp-empty-test std::stable_sort, test round:7, 0.175831 seconds used.
D   07-26 17:38:34.203  26896   26896    cpp-empty-test std::stable_sort, test round:8, 0.172404 seconds used.
D   07-26 17:38:34.382  26896   26896    cpp-empty-test std::stable_sort, test round:9, 0.175211 seconds used.
D   07-26 17:38:34.558  26896   26896    cpp-empty-test std::stable_sort, test round:10, 0.174865 seconds used.
D   07-26 17:38:34.760  26896   26896    cpp-empty-test std::sort(order not stable), test round:1, 0.166891 seconds used.
D   07-26 17:38:35.026  26896   26896    cpp-empty-test std::sort(order not stable), test round:2, 0.220831 seconds used.
D   07-26 17:38:35.153  26896   26896    cpp-empty-test std::sort(order not stable), test round:3, 0.120922 seconds used.
D   07-26 17:38:35.277  26896   26896    cpp-empty-test std::sort(order not stable), test round:4, 0.121727 seconds used.
D   07-26 17:38:35.400  26896   26896    cpp-empty-test std::sort(order not stable), test round:5, 0.120830 seconds used.
D   07-26 17:38:35.524  26896   26896    cpp-empty-test std::sort(order not stable), test round:6, 0.120971 seconds used.
D   07-26 17:38:35.647  26896   26896    cpp-empty-test std::sort(order not stable), test round:7, 0.120970 seconds used.
D   07-26 17:38:35.770  26896   26896    cpp-empty-test std::sort(order not stable), test round:8, 0.121041 seconds used.
D   07-26 17:38:35.893  26896   26896    cpp-empty-test std::sort(order not stable), test round:9, 0.120724 seconds used.
D   07-26 17:38:36.016  26896   26896    cpp-empty-test std::sort(order not stable), test round:10, 0.121152 seconds used.
D   07-26 17:38:36.233  26896   26896    cpp-empty-test std::sort, no optimize orderOfArrival storage, original implement, test round:1, 0.212735 seconds used.
D   07-26 17:38:36.459  26896   26896    cpp-empty-test std::sort, no optimize orderOfArrival storage, original implement, test round:2, 0.214915 seconds used.
D   07-26 17:38:36.683  26896   26896    cpp-empty-test std::sort, no optimize orderOfArrival storage, original implement, test round:3, 0.216309 seconds used.
D   07-26 17:38:36.939  26896   26896    cpp-empty-test std::sort, no optimize orderOfArrival storage, original implement, test round:4, 0.216780 seconds used.
D   07-26 17:38:37.184  26896   26896    cpp-empty-test std::sort, no optimize orderOfArrival storage, original implement, test round:5, 0.238538 seconds used.
D   07-26 17:38:37.579  26896   26896    cpp-empty-test std::sort, no optimize orderOfArrival storage, original implement, test round:6, 0.385009 seconds used.
D   07-26 17:38:38.006  26896   26896    cpp-empty-test std::sort, no optimize orderOfArrival storage, original implement, test round:7, 0.416112 seconds used.
D   07-26 17:38:38.341  26896   26896    cpp-empty-test std::sort, no optimize orderOfArrival storage, original implement, test round:8, 0.320803 seconds used.
D   07-26 17:38:38.565  26896   26896    cpp-empty-test std::sort, no optimize orderOfArrival storage, original implement, test round:9, 0.218719 seconds used.
D   07-26 17:38:38.788  26896   26896    cpp-empty-test std::sort, no optimize orderOfArrival storage, original implement, test round:10, 0.218715 seconds used.
D   07-26 17:38:38.880  26896   26896    cpp-empty-test std::sort, optimize orderOfArrival storage, test round:1, 0.090458 seconds used.
D   07-26 17:38:38.973  26896   26896    cpp-empty-test std::sort, optimize orderOfArrival storage, test round:2, 0.091338 seconds used.
D   07-26 17:38:39.065  26896   26896    cpp-empty-test std::sort, optimize orderOfArrival storage, test round:3, 0.090985 seconds used.
D   07-26 17:38:39.156  26896   26896    cpp-empty-test std::sort, optimize orderOfArrival storage, test round:4, 0.090257 seconds used.
D   07-26 17:38:39.249  26896   26896    cpp-empty-test std::sort, optimize orderOfArrival storage, test round:5, 0.091345 seconds used.
D   07-26 17:38:39.342  26896   26896    cpp-empty-test std::sort, optimize orderOfArrival storage, test round:6, 0.092173 seconds used.
D   07-26 17:38:39.435  26896   26896    cpp-empty-test std::sort, optimize orderOfArrival storage, test round:7, 0.091424 seconds used.
D   07-26 17:38:39.526  26896   26896    cpp-empty-test std::sort, optimize orderOfArrival storage, test round:8, 0.090484 seconds used.
D   07-26 17:38:39.621  26896   26896    cpp-empty-test std::sort, optimize orderOfArrival storage, test round:9, 0.090750 seconds used.
D   07-26 17:38:39.712  26896   26896    cpp-empty-test std::sort, optimize orderOfArrival storage, test round:10, 0.089847 seconds used.

@minggo
Copy link
Contributor

minggo commented Jul 26, 2016

What's your empty project? Will you share it?

@halx99
Copy link
Contributor Author

halx99 commented Jul 26, 2016

My project is based on cocos2d-x-3.9 and use gcc to compile

@halx99
Copy link
Contributor Author

halx99 commented Jul 26, 2016

Does the cocos2d-x-3.12 replace gcc by clang?

@minggo
Copy link
Contributor

minggo commented Jul 26, 2016

yep, because gcc is deprecated since ndk r11+, and will be removed in future

@halx99
Copy link
Contributor Author

halx99 commented Jul 26, 2016

There other 2 difference with your project:

  1. My android.mk no LOCAL_ARM_MODE := arm
  2. My Application.mk not specific APP_ABI := armeabi
    I think the above differences do not affetct the different performance test result.

@minggo
Copy link
Contributor

minggo commented Jul 26, 2016

change to use LOCAL_ARM_MODE := arm is to fix #16033

bool nodeComparisonLess(Node* n1, Node* n2)
{
return(n1->_localZOrder.value < n2->_localZOrder.value);
#if defined(_M_X64) || defined(_LP64) || defined(__x86_64) || defined(_WIN64)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which platform will define these macros?

Copy link
Contributor Author

@halx99 halx99 Jul 27, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

windows 64: _WIN64, _M_X64
linux 64: __x86_64, __LP64__, __amd64
apple (mac or ios) 64: _LP64, __LP64__ 

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need it for Android 64 too.

Copy link
Contributor Author

@halx99 halx99 Jul 27, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The android is based on linux, so I think linux 64 specific macros can handle it.
I just have checked the android arm64-v8a: the macro __LP64__ and _LP64 are worked well.

The check program:
proj.android-bits-detect.zip

You can just run jni/dobuild.bat and open the generated libs/arm64-v8a/libpseudo.so with UE or EmEditor to search the symbols:_LP64$defined and __LP64__$defined

My result is:

72g n663nidf0 yz f6je

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, have you tested the new codes, and what's the performance?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean change test structure to

union LocalZOrder {
   ...
};
struct SimpleNode{
    LocalZOrder _localZOrder;
};

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new test codes could be:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <vector>
#include <time.h>

#if 0 // for android
#define  LOG_TAG    "cpp-empty-test"
#define  LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#define logfunc(format,...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,(format "\n"),##__VA_ARGS__)
#else
#define logfunc(format,...) printf((format "\n"),##__VA_ARGS__)
#endif

void runPerfromanceFunc()
{
    union LocalZOrder {
        LocalZOrder(int z, unsigned a)
        {
            value = 0;
            detail.z = z;
            detail.a = a;
        }
        struct {
            int z; // The original localZOrder
            unsigned int a; // Order Of Arrival, for avoid sort problem with unstable_sort algorithm.
        } detail;
        long long value; // The value to be used in sort
    };               ///< Local order (relative to its siblings) used to sort the node

    class SimpleNode
    {
    public:
        SimpleNode(int z, unsigned a) : _localZOrder(z, a)
        {
        }
        LocalZOrder _localZOrder;
    };

    std::vector<SimpleNode*> vec2;
    logfunc("test program is %d bits!", sizeof(void*) << 3);

    for (auto i = 0; i < 1000000; ++i)
        vec2.push_back(new SimpleNode(2, i + 1));

    clock_t start = 0;

    for (int i = 0; i < 10; ++i) {
        start = clock();
        std::stable_sort(vec2.begin(), vec2.end(), [](const SimpleNode* l, const SimpleNode* r) {
            return l->_localZOrder.detail.z < r->_localZOrder.detail.z;
        });
        logfunc("std::stable_sort, test round:%d, %lf seconds used.", i + 1, (clock() - start) / (double)CLOCKS_PER_SEC);
    }

    for (int i = 0; i < 10; ++i) {
        start = clock();
        std::sort(vec2.begin(), vec2.end(), [](const SimpleNode* l, const SimpleNode* r) {
            return l->_localZOrder.detail.z < r->_localZOrder.detail.z;
        });
        logfunc("std::sort(order not stable), test round:%d, %lf seconds used.", i + 1, (clock() - start) / (double)CLOCKS_PER_SEC);
    }

    for (int i = 0; i < 10; ++i) {
        start = clock();
        std::sort(vec2.begin(), vec2.end(), [](const SimpleNode* l, const SimpleNode* r) {
            return l->_localZOrder.detail.z < r->_localZOrder.detail.z || (l->_localZOrder.detail.z == r->_localZOrder.detail.z && l->_localZOrder.detail.a < r->_localZOrder.detail.a);
        });
        logfunc("std::sort, no optimize orderOfArrival storage, original implement, test round:%d, %lf seconds used.", i + 1, (clock() - start) / (double)CLOCKS_PER_SEC);
    }

    for (int i = 0; i < 10; ++i) {
        start = clock();
        std::sort(vec2.begin(), vec2.end(), [](const SimpleNode* l, const SimpleNode* r) {
            return l->_localZOrder.value < r->_localZOrder.value;
        });
        logfunc("std::sort, optimize orderOfArrival storage, test round:%d, %lf seconds used.", i + 1, (clock() - start) / (double)CLOCKS_PER_SEC);
    }
}

int main(int, char**)
{
    runPerfromanceFunc();

#if defined(_WIN32)
    getchar();
#endif
    return 0;
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean you should test the performance on iOS and Android again with adding the macro.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why again: the test code already contains the different situations.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To test if the macro takes effect. Especially for iOS and Android.

@halx99
Copy link
Contributor Author

halx99 commented Jul 27, 2016

@minggo For andorid: you can use the simple project to detect it: proj.android-bits-detect.zip, my test result is __LP64__ and _LP64 is ok.
For iOS: I have a MAC book & check it on xcode, the _LP64 is defined.

@minggo
Copy link
Contributor

minggo commented Jul 27, 2016

Yep, it takes effect.

@minggo minggo merged commit 3a14388 into cocos2d:v3 Jul 27, 2016
@minggo minggo added this to the 3.13 milestone Jul 27, 2016
@minggo minggo changed the title #improve node sort performance by std::sort + long long (_localZOrder) #improve node sort performance by std::sort + long long (_localZOrder) for 64-bit Jul 27, 2016
std::uint32_t a; // Order Of Arrival, for avoid sort problem with unstable_sort algorithm.
} detail;
std::int64_t value; // The value to be used in sort
} _localZOrder; ///< Local order (relative to its siblings) used to sort the node
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The codes have problem. For example, let's assume there are two nodes:

node1: z = 0, a = 1, then value is 0x0000000100000000
node2: z = 1, a = 0, then value is 0x0000000000000001

node2.vlaue < node1.value, then the render sequence is node2, node1, it is wrong. The correct sequence should be node1, node2 because the node2.z is bigger. You can test cpp-emptey-test on Mac or iOS, you can see now the close item is hidden by background.

If we change it like this,

union {
        struct {
            std::int32_t z; // The original localZOrder
            std::uint32_t a; // Order Of Arrival, for avoid sort problem with unstable_sort algorithm.
        } detail;
        std::int64_t value; // The value to be used in sort
    } _localZOrder;  

then it may have issue of z is negative, for example

node1: z = -1, a = 1, then value is -(2^32 + 1)
node2: z = -1, a = 2, then value is -(2^32 + 2)

node2.value < node1.value, so the render sequence is node2, node1. It is wrong, because node2.z == node1.z but node2.a > node2.a.

The above analyzation only takes effect with little endian architecture(x86, arm). If the architecture is big endian, the result is different.

So we can not just use union here. If the union is the only effect for optimization, then we should revert the PR.

Copy link
Contributor Author

@halx99 halx99 Jul 28, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you are right, That's why I storage as a unsigned long long and simulate a int32 storage as follow:

#include <assert.h>
#define CC_LOCALZORDER_ZERO 0x7fffffffULL
class SimpleNode
    {
    public:
        SimpleNode(int z, unsigned int a)
        {
            _localZOrder = 0;
            setLocalZOrder(z);
            setOrderOfArrival(a);
        }

        int getLocalZOrder() const
        {
            return static_cast<int>(((_localZOrder >> 32) & 0xffffffff) - CC_LOCALZORDER_ZERO);
        }

        unsigned int getOrderOfArrival() const
        {
            return static_cast<unsigned int>((_localZOrder) & 0xffffffff);
        }

        void setLocalZOrder(int z)
        {
            _localZOrder = ((CC_LOCALZORDER_ZERO + z) << 32) | (_localZOrder & 0xffffffff);
        }

        void setOrderOfArrival(unsigned int orderOfArrival)
        {
            _localZOrder = (_localZOrder & 0xffffffff00000000) | orderOfArrival;
        }

        std::uint64_t _localZOrder;
    };

    // check value storage
    SimpleNode n1(0, 1);
    SimpleNode n2(1, 0);
    SimpleNode n3(-3, 500);

    assert(n3.getLocalZOrder() == -3);
    assert(n3.getOrderOfArrival() == 500);
    assert(n1._localZOrder < n2._localZOrder);
    assert(n3._localZOrder < n1._localZOrder);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should revert this PR.

Copy link
Contributor Author

@halx99 halx99 Jul 28, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry, I think your analyzation have some problem:

then it may have issue of z is negative, for example

node1: z = -1, a = 1, then value is -(2^32 + 1)
node2: z = -1, a = 2, then value is -(2^32 + 2)

You chould not simple use '+' operation to check the long long value,
Actually:
node1 value is: 0xffffffff00000001 = -4294967295
node2 value is: 0xffffffff00000002 = -4294967294

so, for negative value, except sign bit, other bits specific more large then, acutal value more less.

The root casue is I made a incorrect order, then the correct shoud be follow(only work for little endian arch):

struct 
{
   std::uint32_t a;
   std::int32_t z;
};

And for big endian arch, the original code is ok.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check it by follow code

void checkStorageLE()
{
    union LocalZOrder {
        LocalZOrder(int z, unsigned a)
        {
            value = 0;
            detail.z = z;
            detail.a = a;
        }
        struct {
            unsigned int a; // Order Of Arrival, for avoid sort problem with unstable_sort algorithm.
            int z; // The original localZOrder
        } detail;
        long long value; // The value to be used in sort
    };               ///< Local order (relative to its siblings) used to sort the node

    class SimpleNode
    {
    public:
        SimpleNode(int z, unsigned a) : _localZOrder(z, a)
        {
        }
        LocalZOrder _localZOrder;
    };

    SimpleNode n1(0, 1);
    SimpleNode n2(1, 0);

    SimpleNode nn1(-1, 1);
    SimpleNode nn2(-1, 2);

    bool ok = n1._localZOrder.value < n2._localZOrder.value;
    assert(ok);
    ok = nn1._localZOrder.value < nn2._localZOrder.value;
    assert(ok);
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But i have to revert it first. Could you please send a new PR after i merge the reverted PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@halx99 i have merged the reverted PR. So you can send a new PR now, thanks. And because we start to test v3.13, and the PR will modify the basic codes of cocos2d-x, so i may not include your PR in v3.13 but next version.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will create v3.13 when start testing, and continue merging PR in v3. v3.13 only supports bug fixed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

@cezheng
Copy link
Contributor

cezheng commented Jul 28, 2016

Yes, this PR is causing problems to our game.

@minggo
Copy link
Contributor

minggo commented Jul 29, 2016

i reverted in #16260.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants