Repository navigation
Performance optimization for case_fold - #326
andreasbuhr wants to merge 1 commit into
Conversation
| // One-byte fast path. | ||
| if (cp < 0x100) { | ||
| // ASCII letter fast path. | ||
| if (0x61 <= cp && cp <= 0x7a) { |
There was a problem hiding this comment.
Adding the if (cp < 0xb5) case below seems good to me, but removing the fast-path for the already-folded region [0x61, 0x7a] seems wrong. Is there a reason for it, or was it a mistake?
There was a problem hiding this comment.
Actually I thought about it and it was a deliberate choice to remove it. But it's not important. Important is that there is no more std::lower_bound call for each space, brace, etc, as it was in the past. I am fine both with the fast path and without it.
If you are interested, here is my reasoning. Only read if you really want to know:
I considered six cases and counted the number of comparisons for each case.
Three different classes of characters:
- uppercase A-Z [0x41, 0x5a]
- lowercase a-z [0x61, 0x7a]
- punctuation/whitespace ()*+.. [0x21,0x40]
And two code options:
A: with fast-path for [0x61,0x7a]
B: without fast-path for [0x61,0x7a]
Now let's count the comparisons:
First uppercase A-Z:
Case 1-A:
0x61(false),0x41(true),0x5a(true)
Case 1-B:
0x41(true),0x5a(true)
-> The fast path for lowercase a-z costs us one comparison for each uppercase A-Z
Then lowercase a-z:
Case 2-A:
0x61(true),0x7a(true)
Case 2-B:
0x41(true),0x5a(false),0xb5(true)
-> The fast path for lowercase a-z saves us one comparison for each lowercase a-z
Then punctuation/whitespace:
Case 3-A:
0x61(false),0x41(false),0xb5(true)
Case 3-B:
0x41(false),0xb5(true)
-> The fast path for lowercase a-z costs us one comparison for each punctuation or whitespace
Conclusion:
The fast path for a-z saves us one comparison for each lowercase a-z character, but costs us one comparison for every uppercase character, every punctuation, brace, space etc. Looking at my vba code, I had the impression that there are not more a-z characters than other characters. Combined with my fundamental believe "less code is better" I decided to remove the fast-path.
There was a problem hiding this comment.
reading my own comment I realized we can do even better:
#335
There was one call to std::lower_bound for each space, for each parenthesis, for each newline, and for each bracket. This is not required. See https://www.unicode.org/Public/UCD/latest/ucd/CaseFolding.txt and https://www.fileformat.info/info/charset/UTF-32/list.htm
a44a3ee to
58ac198
Compare
|
I rebased on develop |
There was one call to std::lower_bound for each space, for each parenthesis, for each newline, and for each bracket. This is not required.
See https://www.unicode.org/Public/UCD/latest/ucd/CaseFolding.txt and https://www.fileformat.info/info/charset/UTF-32/list.htm