Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 34.4k
src: use DataView for B.{read,write}{Float,Double}#2897
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
Uh oh!
There was an error while loading. Please reload this page.
Conversation
bnoordhuis commented Sep 16, 2015
I have to say I'm not really a fan of how this adds a new property to the Buffer prototype. |
targos commented Sep 16, 2015
Results of buffer benchmarks on current master before and after applying this patch: https://gist.github.com/targos/438a9cc9dc48fa178729 |
Fishrock123 commented Sep 16, 2015
cc @trevnorris |
skomski commented Sep 16, 2015
@bnoordhuis performance or api burden? Because I did not plan to document this property and I can rename to make it more clear. @targos My patch can't be only difference in your benchmark. This patch could only have a big impact for float and double related tests or insignificant slow down for example buffer-creation but cannot improve buffer-iterate. |
targos commented Sep 16, 2015
@skomski you are right, I ran the |
lib/buffer.js Outdated
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.
Should be configurable and probably enumerable
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.
What about this:
Object.defineProperty(Buffer.prototype,'dataView',{get: function(){returnthis.dataView=newDataView(this.buffer,this.byteOffset,this.byteLength);},configurable: true,enumerable: true});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.
You can't set something that only has a getter. The current body of the getter is fine.
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.
Right, my bad. So the body should call Object.defineProperty(this, 'dataView',{value: ... });
I don't like the fact that we need two properties (dataView and _dataView) for one.
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.
I'm with @targos here. We do that some other places too.
domenic commented Sep 16, 2015
I like adding a dataView property to the prototype, from an API perspective. But it should be documented. If it's not going to be documented then just use the _dataView property directly. |
trevnorris commented Sep 16, 2015
Let me investigate why this is faster. The v8 API should be comparable in terms of performance. |
trevnorris commented Sep 16, 2015
There are several extra checks that don't need to be done in the current implementation. A quick refactor removed the performance difference between the two. This would be the better approach. @skomski If you'd like to take this on, I can point you at which checks need to be changed/removed. Otherwise I can throw up a PR. Thanks for investigating the performance here. In the last refactor I went overly paranoid w/ checking to make sure nothing slipped through the cracks. |
domenic commented Sep 16, 2015
I think there's independent value in (a) adding an easy dataView accessor; (b) removing all that C++ code in favor of using the stuff V8 already has. So this still seems like a good change to me... |
ChALkeR commented Sep 16, 2015
|
trevnorris commented Sep 16, 2015
I don't believe it's a good idea to mutate the object (i.e. add property after instantiation). Which would in turn mutate the ObjectMap. Everything else in Buffer is either attached to the prototype or is statically assigned. In terms of performance, difference between the two is within the margin of error. Our implementation is slightly faster if In terms of compatibility difference, The first can be addressed by setting Setting object property after instantiation is my concern. Can anyone think of a way to get around it? |
4fa0061 to 145feebCompareskomski commented Sep 17, 2015
@trevnorris Pushed an update that simply defines the property |
trevnorris commented Sep 17, 2015
@skomski Issue is as I mentioned:
Any Buffers created from C++ won't have this property set. So we'll then have two object maps being passed around. Solutions would be to also set the property in C++ (though I have reservations on the performance impact that would have, since JS operations in native are slow) or... Not sure. Have looked for a way to do this without setting a property on the object, but haven't found one. If it wasn't for needing to store a value on the instantiated Buffer (primarily because the operation needs to be performed in C++ and JS) I'd be +1 for this change. And if someone can find a way I think that would be great. Until then I'm inclined to say the better approach is to remove the overzealous checks. Which would still give comparable performance. |
trevnorris commented Sep 17, 2015
Example script to demonstrate my issue: 'use strict';letb=newBuffer(16);for(leti=0;i<1e4;i++)b.write('hi all');b.readFloatLE(0);b.write('hi all');Running this script currently: Running script with this PR (before the recent change of placing the Altering the map will cause a deoptimization. Now, if we could simply immediately set it in JS after creating the |
Adds lazy-initialized dataView property to Buffer Removes C++ functions: ReadFloat, WriteFloat, ReadDouble, WriteDouble About 37,5% faster
145feeb to 576af3bComparechrisdickinson commented Sep 29, 2015
If you wanted to avoid mutating the object, add a vardataViewMap=newWeakMap()Object.defineProperty(Buffer.prototype,'dataView',{enumerable: true,get: function(){if(!dataViewMap.has(this)){vardv=newDataView(this.buffer,this.byteOffset,this.byteLength);dataViewMap.set(this,dv);returndv;}returndataViewMap.get(this);}});Unsure what affect this would have on the perf of backing the buffer methods with dataview, but it should solve the mutated object problem. |
trevnorris commented Sep 29, 2015
Pending #3080 the time gap between implementations will be around 5ns. There are additional optimizations to do afterwards, but will wait until the PR lands. |
jasnell commented Mar 22, 2016
What's the status on this one? @trevnorris any reason to keep this open? |
trevnorris commented Mar 23, 2016
I haven't benchmarked recently, but last I checked this was within 10-20 ns of our implementation if there are enough writes to discount the time it takes to create the |
jasnell commented Mar 27, 2016
Noted. @skomski ... is this still something you wish to pursue? |
7da4fd4 to c7066fbComparec133999 to 83c7a88Comparejasnell commented Feb 28, 2017
Closing given the lack of progress |
Adds lazy-initialized dataView property to Buffer
Removes C++ functions: ReadFloat, WriteFloat, ReadDouble, WriteDouble
About 37,5% faster