Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by zaino · May 16, 2013 at 03:33 AM · performancesortinggeneric.list

Performance of float.CompareTo

Hi good people, I'll go straight to the point. C# script. I was sorting a List like this:

 mColliders.Sort( (a, b) => ((a.Up.x-a.Radius).CompareTo(b.Up.x-b.Radius)));

and the performance on a ~250 long list were horrible, both in the editor and on the iPhone, roughly 3ms.

Then, just to test, I rewrote it with a dumb lamda like this:

 mColliders.Sort( (a, b) => {
                 if (a.Up.x-a.Radius>b.Up.x-b.Radius) return 1;
                 else if (a.Up.x-a.Radius<b.Up.x-b.Radius) return -1;
                 else return 0;
                 });

Much better, went down to ~0.6ms. Does anybody here have an idea of why the CompareTo was being so damn slow?

Thanks!

Comment
Add comment · Show 5
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image whydoidoit · May 16, 2013 at 07:36 AM 0
Share

The faster implementation of your sort would be to only do the calculation once:

 mColliders.Sort( (a, b) => {
       var diff = (a.Up.x - a.Radius) - (b.Up.x - b.Radius);
       return diff < 0 ? -1 : (diff == 0 ? 0 : 1); 
     });
avatar image zaino · May 16, 2013 at 02:51 PM 0
Share

The point is the title, not the petty details. Why on earth would the implementation matter to you, since I'm asking specifically about CompareTo and it's in both implementations? Radius does not do any calculation, The lambda is willingly sloppy, to show how silly slow is the compareTo.

avatar image yoyo · May 16, 2013 at 03:22 PM 0
Share

Also note you only need to return negative/0/positive, not necessarily -1/0/+1 -- so from @whydoidoit's comment above, just return diff directly.

avatar image zaino · May 16, 2013 at 03:42 PM 0
Share

Yap well aware of that. As I said, the lambda there is sloppy on purpose, to stress the inefficiency of the CompareTo.

avatar image zaino · May 18, 2013 at 08:07 PM 0
Share

@yoyo - note that the comparer needs an int, so the difference must be treated so that you don't return 0 for values like between -0.5f and 0.5f, in case you round, (-1, 1) if you truncate, etc. You can also scale the difference and just cast to int.

1 Reply

· Add your reply
  • Sort: 
avatar image
2
Best Answer

Answer by yoyo · May 16, 2013 at 05:20 AM

float.CompareTo is mostly likely converting a float value type into an object and then converting back to a value type. This boxing and unboxing process is slow, possibly worse in the iPhone .NET implementation.

Comment
Add comment · Show 11 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image whydoidoit · May 16, 2013 at 07:34 AM 1
Share

$$anonymous$$ay well be, but it would be a terrible implementation of the fully typed version!

Just shows you can't trust the frameworks performance without actually measuring it :)

avatar image zaino · May 16, 2013 at 02:44 PM 0
Share

Totally agree with you. I tought about auto boxing but why would it do that with a float? If this is the case, horrible implementation fail.

avatar image yoyo · May 16, 2013 at 03:20 PM 0
Share

What's the type of mColliders? Is it just List, or List(T)? If the latter then it shouldn't need to box the parameters. Either way, best way to find out for sure is to disassemble the IL and see what it's doing. Or just pick the fastest solution and move on ...

avatar image Bunny83 · May 16, 2013 at 04:44 PM 1
Share

The tool of your choice: ILSpy ;)

It can decompile any .NET code into IL and most .NET code into C# (and VB .NET, well...)

avatar image whydoidoit · May 16, 2013 at 04:51 PM 1
Share

This is actually the mscorlib (subset) version:

 public int CompareTo(float value)
 {
     if (float.IsPositiveInfinity(this) && float.IsPositiveInfinity(value))
     {
         return 0;
     }
     if (float.IsNegativeInfinity(this) && float.IsNegativeInfinity(value))
     {
         return 0;
     }
     if (float.IsNaN(value))
     {
         if (float.IsNaN(this))
         {
             return 0;
         }
         return 1;
     }
     else
     {
         if (float.IsNaN(this))
         {
             if (float.IsNaN(value))
             {
                 return 0;
             }
             return -1;
         }
         else
         {
             if (this == value)
             {
                 return 0;
             }
             if (this > value)
             {
                 return 1;
             }
             return -1;
         }
     }
 }
Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

18 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Will unity sort Drawcalls to reduce overhead ? 0 Answers

Coin Magnet Performance Issue Mobile 3 Answers

Does Unity's Dictionary performance depend on number of dictionaries? 0 Answers

Sendmessage performance 3 Answers

What kind of performance impact does looping anmiations have on a game? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges