-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
faster wcwidth with lookup table #798
Conversation
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.
Nice
src/InputHandler.ts
Outdated
} | ||
return function (num) { | ||
num = num | 0; | ||
return (num < 65536) ? (table[num >> 2] >> ((num & 3) * 2)) & 3 : wcwidthHigh(num); |
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 this have an early return for ascii characters as they are the vast majority, or would that not boost perf much at this point?
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.
Could do with a comment explaining the bit shifting part
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.
@Tyriar Well it gives 5% speedup to exclude the ascii range from the shifting & lookup. So yeah gonna change it.
src/InputHandler.ts
Outdated
return 1; | ||
} | ||
let table = new Uint8Array(16384); | ||
for (let i = 0; i < 16384; ++i) { |
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.
Does this increase startup in a noticeable way?
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.
It adds 10 to 16 ms.
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.
Is that 10-16ms when the first terminal is launched or when the script is loaded?
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.
When the script loads, it is done during import.
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.
Created a follow up 😃 #799
src/InputHandler.ts
Outdated
} | ||
return 1; | ||
} | ||
let table = new Uint8Array(16384); |
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.
A named variable/comment explaining 16384 would be good ((65536-4)/4+1?).
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.
Also this needs to be conditional and fallback to a regular array for browsers without support
- commenting the bit shifts - switching to Uint32Array - conditional for TypedArray - fixing Math.floor slowdown in bisearch
@Tyriar Changed the table to |
@jerch this would mean doing it on either terminal creation ( |
Addressed the lazy loading with the last commit, the lookup table is created at the first call with a char > 127. Benchmarks with node V8 on my machine are now:
|
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.
Looks good to me, I'm planning on pulling this into its own file #800 and doing a clean up so the code style is a little closer to the rest of the codebase 👍
src/InputHandler.test.ts
Outdated
})({nul: 0, control: 0}); // configurable options | ||
|
||
describe('wcwidth', () => { | ||
it('same as old implementation for BMP and individual higher', () => { |
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.
Can't get more confident about no functional changes than this 😉
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.
haha :D
@jerch CI failed on macOS:
Might need to increase the timeout of that test? https://travis-ci.org/sourcelair/xterm.js/jobs/254546569 |
Hmm yeah seems the travis OSX boxes are pretty busy from time to time and tend timeout longer running tests. The test runs in under a second here... |
This PR optimizes
wcwidth
by using a lookup table for BMP characters. For a BMP char it boils down to a simple table lookup with some shifting magic to pack the data into 16k bytes. Speedup is at least 10 times. Equality tests included.