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

Improve write performance #99

Closed
wants to merge 1 commit into from

Conversation

BridgeAR
Copy link

See nodejs/node#19289. I did not run dedicated benchmarks here.

@mscdex
Copy link
Owner

mscdex commented Mar 11, 2018

Did you check previous node branches to see how this change affects them (positively or negatively)?

@BridgeAR
Copy link
Author

I ran those from Node.js 6 > 10-pre and either the performance is identical or better.

@BridgeAR
Copy link
Author

4 is identical as well.

@mscdex
Copy link
Owner

mscdex commented Mar 12, 2018

I just tested these on each node branch (including master) and my versions of these functions, without the validation code, perform exactly the same as the previous implementations (before this PR). Here's what I used to benchmark:

const n = 1e9;
const b = Buffer.alloc(4);

function writeUInt32BE(buf, value, offset) {
  buf[offset++] = (value >>> 24);
  buf[offset++] = (value >>> 16);
  buf[offset++] = (value >>> 8);
  buf[offset++] = value;
  return offset;
}
console.time('original');
for (var i = 0; i < n; ++i)
  writeUInt32BE(b, 0xffff, 0);
console.timeEnd('original');

/*
function writeUInt32BE(buf, value, offset) {
  buf[offset + 3] = value;
  value = value >>> 8;
  buf[offset + 2] = value;
  value = value >>> 8;
  buf[offset + 1] = value;
  value = value >>> 8;
  buf[offset] = value;
  return offset + 4;
}
console.time('new');
for (var i = 0; i < n; ++i)
  writeUInt32BE(b, 0xffff, 0);
console.timeEnd('new');
*/

Just comment out one and uncomment the other and compare. For me, I get ~1033ms.

@BridgeAR
Copy link
Author

To me it looks like the code is going to be inlined and this does not benchmark what should be benchmarked. Changing 0xffff to a number that is increased with each call should prevent this and yield a clearer result.

@mscdex
Copy link
Owner

mscdex commented Mar 12, 2018

Ok I modified the loop to:

  if (i % 2 === 0)
    writeUInt32BE(b, 0xffff, 0);
  else
    writeUInt32BE(b, 0xff, 0);

and now on node master, the original implementation (~3480ms) is faster than this PR (~3520ms).

Also there is a strange performance issue starting with node v9 where it takes over twice as long as previous node branches. Node v8 and older take only ~1400-1500ms for either implementation.

EDIT: switch the loop to writeUInt32BE(b, i, 0) gets performance back to node v8 and earlier.... strange. Also with that inside the loop, the new implementation does seem to be faster.

@BridgeAR
Copy link
Author

Ok, I ran a couple of different benchmarks again and it somewhat seems to depend on the input size what function is faster. Since there is no ideal solution, I am going to close this.

@BridgeAR BridgeAR closed this Apr 12, 2018
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.

2 participants