"extractFields" function triggers Buffer.indexOf polyfill slow path
gkjohnson opened this issue · comments
Hello! When I was doing perf analysis on my app I noticed that there was a lot of time spent in extractFields and Buffer.indexOf and noticed a quirk of the Buffer.indexOf polyfill implementation -- specifically it creates a new buffer and uses a custom Javascript search function rather than the native Uint8Array.indexOf
implementation when a string is passed in. Here's a bit more of a breakdown:
- extractFields calls field.indexOf( '=' )
- This calls bidirectionalIndexOf in the buffer package which creates a new array from the string argument
- And ultimately calls this arrayIndexOf function instead of the native implementation to search for the index.
Here's a quick benchmark to run to show the performance difference. I'm seeing a 10-15 times improvement when passing a number into indexOf
rather than a string. Note that this is when running a browser / node with the polyfill. When running this benchmark with the native node Buffer implementation there are still some small improvements but not nearly as drastic:
import { Buffer } from 'buffer';
const buff = Buffer.alloc( 10000 );
buff[ 5000 ] = 61;
const c = '=';
console.time( 'String' );
for ( let i = 0; i < 1000; i ++ ) {
buff.indexOf( c );
}
console.timeEnd( 'String' );
const n = '='.charCodeAt( 0 );
console.time( 'Number' );
for ( let i = 0; i < 1000; i ++ ) {
buff.indexOf( n );
}
console.timeEnd( 'Number' );
It seems that this gets run in a pretty tight loop so it should be worth switching over to something like field.indexOf( 61 )
. If that sounds agreeable I can submit a PR with the change!
Hey thanks for this investigation! Would love to see a PR w/ the change!
@brianc Great thanks! I'll submit one in a bit.
And a bit of an unrelated question but are there release notes for the different versions of the library? I just updated from 2.0.2 to 2.6.2 but it doesn't look like the different versions are listed in the releases page or the HISTORY.md file.
Its likely we just forgot to update HISTORY.md