-
Notifications
You must be signed in to change notification settings - Fork 32
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
Your performance tests are incorrect #19
Comments
Hey @kogarashisan, looks like you know a lot about making accurate benchmarks. Thanks for making a test that uses |
Also it loks like your tests at http://jsperf.com/js-inheritance-method-calls/3 don't use all of the techniques you mentioned in https://github.com/kogarashisan/PerfTests . For example, you're using a counter that goes up to 100,000 and you don't have any code to prevent inlining. Was this intentional? I'm also wondering why you create a loop inside the test-case, since the test cases themselves are already executed iteratively. |
If you calculate the time to construct a pair of objects for any given library, and then divide it by the time of 100000 pairs of method calls for that library, you will get the error that is introduced by the object creation. For the fastest libraries, it's much less than 1% (I checked that with calculator), so can be neglected. Another way would be to create a pair of objects for each inheritance model in preparation section, So between these two ways, i have chosen mine, cause it creates many pairs of objects instead of one. If there was only one pair - then JS engine could introduce optimizations to polymorphic methods (they would be still polymorphic, but they could be a bit faster). For example, in "proto" methods are assigned in a clusure, so potentially it can be faster, if you test it against only one object. So one pair is good, but many pairs is better. I'm not a benchmarking guru, that's not my specialization. These tests can be improved by adding a warm-up loop in the preparation section, in theory this can reduce deviation a bit... For "proto" I'm using the same techniques as for all others:
If you have more questions - feel free to ask. |
Ohh, i see. The method being called has to be fat - not the contents of the loop - of course. Also, I was confused by So now I get everything except, why not separate object instantiation from method calling? While the object instantiation might be negligible in the test you wrote at http://jsperf.com/js-inheritance-method-calls/3 , it doesn't show you the performance of instantiation (which may be important in systems that create a LOT of objects). How would you go about that? Remove the method calls and move the instantiation into the loop? |
but... there is a separate test suite for that: By the way, did you know about existence of https://github.com/ericelliott/stampit |
Ah i see. I still would pull out the object construction stuff unless it is required for a good performance test. Event if it is negligible, i'd feel better about the test. I haven't seen stampit before, but the methods aren't very well explained - not sure what the difference is between a lot of the methods (compose vs mixIn for example). I created two additional revisions, one that removes the instance creation from the method call test: http://jsperf.com/js-inheritance-method-calls/4 and a version of your object construction test that includes proto in the same way you included it in the other test: |
Sorry, but seems like your tests may be wrong. For method calls you need a warm-up loop, like this:
Second: i would make method calls of equal length. Some years ago, call to
P.S. Also, I mentioned Stampit as example that you are inventing a wheel... your model looks similar. And when you assign methods in a closure - they become slower, see this |
I don't understand. I created my tests from your test: http://jsperf.com/js-inheritance-method-calls/3 . The only thing i changed there was to remove the instance creation in the individual tests (i moved them to the preparation code section). Where is the warm up code in your test? Ah i see about stampit. Well i created proto for its interface, not to be fast. I'm happy that it has performance on par with many of these other fast inheritance libraries. There are also performance improvements I may implement without changing the basic way proto works. |
"Where is the warm up code in your test?" - in my tests it's not needed, cause they invoke P.S. I have just noticed, that my Native test produces different results, when you run it several times in a row. This means that my version is not so perfect, as I expected - numbers should be stable. I will try to consult someone who knows better. |
How's this? http://jsperf.com/js-inheritance-method-calls/5 And was there anything you could see wrong with this one: http://jsperf.com/js-inheritance-object-construction/2 ? It'd be nice if we could agree on a set of tests to link to from each of our projects. |
http://jsperf.com/js-inheritance-object-construction/2 - seem okay. http://jsperf.com/js-inheritance-method-calls/5 - Oh, my... this is very bad, but it's my fault :) I know, that V8 constantly recompiles methods, that are actively used, but I don't know this process in depth. Your "ClassManager/Browser/Polymorphic" is faster then mine. It's just a theory, but seems like it's optimized despite existence of warm-up loop. Looks like these tests need to be improved. Here is a suggestion: in preparation section create 5 pairs of objects, instead of one. And each model test should call That's what I will try myself in a couple of days, when I have time. I will also study assembler output of each test to better understand what's happening. |
It looks like adding 5 method calls greatly reduced the lead Native had. I was too lazy to create new classes for each, but I alternated A and B for each to create 5 instances, and that seemed to work. Check it out here: |
Improved quality of my tests, added a couple of models (not "proto") and explanation about Native. |
There's a lot of shitty class models out there, yes. You don't have to promote proto, but its api is the cleanest in my opinion, its one of the only ones that's compatible with other inheritance libraries, and seems like one of the fastest. I don't regret spending time making it. |
"but its api is the cleanest in my opinion" - no. |
I apologize. That was rude comment. |
I accept your apology. And what I meant that proto is "compatible with other inheritance libraries" is that you can build classes with proto that inherit from native objects, which includes objects generated from other inheritance libraries. I've had a hard time finding inheritance libraries that do that. |
Hello to all LikedIn development team!
I saw this issue: #17
but there is a reason to create another one. You indeed incorrectly mix object construction time with object creation and method calls, but proposed tests are also wrong.
It's not good to deceive people, but I do not insist that you replace the link in your README.
Just have a look at this better version of JS inheritance performance tests:
Tests have their own repository with explanation of everything (this may also interest you): https://github.com/kogarashisan/PerfTests
@fresheneesz And here is the version, which includes "proto" from the referenced issue (you can see, that it's indeed slower):
http://jsperf.com/js-inheritance-method-calls/3
P.S. You may also have a look at my ClassManager: https://github.com/kogarashisan/ClassManager
The text was updated successfully, but these errors were encountered: