Skip to content
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

Partially solves perf issues with the UInt8Array checks. #304

Closed
wants to merge 3 commits into from

Conversation

mcollina
Copy link
Member

@mcollina mcollina commented Jun 27, 2017

Fixes #302

This is a partial fix.

Node 6.11, using readable-stream 2.2.11:

benchThrough2*10000: 5148.149ms

Node 6.11, using readable-stream 2.3.2:

benchThrough2*10000: 18112.640ms

Node 6.11, using this patch:

benchThrough2*10000: 6491.796ms

I think we can do better.

cc @bmeurer

@mcollina mcollina requested a review from calvinmetcalf June 27, 2017 17:11
@mcollina
Copy link
Member Author

Using instanceof results in a better:

benchThrough2*10000: 5649.387ms

Copy link
Contributor

@calvinmetcalf calvinmetcalf left a comment

Choose a reason for hiding this comment

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

looks good, do you also want me to update processNextickArgs to add that other case statement ?

Copy link
Member

@bmeurer bmeurer left a comment

Choose a reason for hiding this comment

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

As discussed separately, the instanceof check is not semantically equivalent to the type check carried out via O.p.toString, but I suppose it's OKish.

build/files.js Outdated
function _uint8ArrayToBuffer(chunk) {
return Buffer.from(chunk);
}
function _isUint8Array(obj) {
return Object.prototype.toString.call(obj) === '[object Uint8Array]' || Buffer.isBuffer(obj);
return Buffer.isBuffer(obj) || (typeof obj !== 'string' && obj instanceof OurUint8Array);
Copy link
Member

Choose a reason for hiding this comment

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

Why not typeof obj === 'object'?

Copy link
Member

Choose a reason for hiding this comment

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

Actually now that I think about it, the typeof check is just unnecessary complexity. instanceof itself already does a type check anyways (as one of the first steps).

function _uint8ArrayToBuffer(chunk) {
return Buffer.from(chunk);
}
function _isUint8Array(obj) {
return Object.prototype.toString.call(obj) === '[object Uint8Array]' || Buffer.isBuffer(obj);
return Buffer.isBuffer(obj) || typeof obj !== 'string' && obj instanceof OurUint8Array;
Copy link
Member

Choose a reason for hiding this comment

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

Same.

function _uint8ArrayToBuffer(chunk) {
return Buffer.from(chunk);
}
function _isUint8Array(obj) {
return Object.prototype.toString.call(obj) === '[object Uint8Array]' || Buffer.isBuffer(obj);
return Buffer.isBuffer(obj) || typeof obj !== 'string' && obj instanceof OurUint8Array;
Copy link
Member

Choose a reason for hiding this comment

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

Same.

@@ -180,11 +180,12 @@ const headRegexp = /(^module.exports = \w+;?)/m
/(?:var|const) Buffer = require\('buffer'\)\.Buffer;/
, `/*<replacement>*/
const Buffer = require('safe-buffer').Buffer
const OurUint8Array = global.Uint8Array || function () {}
Copy link
Member

Choose a reason for hiding this comment

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

Another thing: Use var instead of const here (and in the other files below), to ensure that the instanceof optimization definitely triggers.

Copy link
Member Author

Choose a reason for hiding this comment

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

we are passing through babel anyway, these are all vars.

@mcollina
Copy link
Member Author

@bmeurer thanks, updated.

@kgryte
Copy link

kgryte commented Jun 28, 2017

The move to using instanceof will fail for cross-realm Uint8Array objects (e.g., from iframes or, depending on the setup/Node.js version, different node V8 vm's). Is that a concern?

In contrast, the Object.prototype.toString() approach supports cross-realm objects.

@mcollina
Copy link
Member Author

I do not think so. Considering the cost of using the toString() approach, I think it's a trade-off that we must accept.

@bmeurer
Copy link
Member

bmeurer commented Jun 28, 2017

Ideally there'd be an instance type check for Uint8Array and friends. instanceof doesn't really check whether the object is an Uint8Array, but rather if it has a certain prototype, which is obviously realm specific.

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.

UInt8Array check slowing things down
4 participants