-
Notifications
You must be signed in to change notification settings - Fork 766
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
[READY] Use struct of arrays for static code_points object #1140
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1140 +/- ##
==========================================
+ Coverage 97.69% 97.69% +<.01%
==========================================
Files 90 90
Lines 7058 7069 +11
==========================================
+ Hits 6895 6906 +11
Misses 163 163 |
9342a56
to
0cf0422
Compare
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.
Thanks for the PR. To be thorough, I compared the time it takes to compile the library and the resulting size with and without the proposed changes on platforms we support:
Platform | Compilation time (s) | Library size (MB) | ||
---|---|---|---|---|
Before | After | Before | After | |
Ubuntu 18.04 64-bit (GCC 7.3.0) | 26.56 | 25.79 | 19.59 | 7.32 |
macOS 10.14 (Apple Clang 10.0.0) | 29.16 | 28.20 | 7.09 | 7.30 |
Windows 7 64-bit (MSVC 15) | 30.62 | 30.39 | 7.86 | 6.99 |
The results were obtained by running time ./build.py --no-regex
. There is a small decrease in compilation time for all platforms, a huge size reduction on Linux (as expected), a non negligible decrease on Windows, and a minor increase on macOS.
Reviewed 2 of 3 files at r1, 1 of 1 files at r2, 1 of 1 files at r3.
Reviewable status: 1 of 2 LGTMs obtained
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.
Reviewable status: 1 of 2 LGTMs obtained
update_unicode.py, line 51 at r3 (raw file):
std::array< char[{folded_case_size}], {size} > folded_case; std::array< char[{swapped_case_size}], {size} > swapped_case; std::array< bool, {size} > is_letter;
I wonder if we should really use a bitset here. A std::array of bools is a large overhead of unused bits. For an array of 10,000 bools:
bash-3.2$ ./array
Array: Size: 10000
Bitset: Size: 1256
Possible early optimisation, but this would also have better cache coherency as well as saved padding.
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.
Reviewable status: 1 of 2 LGTMs obtained
update_unicode.py, line 501 at r3 (raw file):
def CppLength( utf8_code_point ):
I think this could benefit from a comment explaining what it does. It would seem to me that the len( bytes() ) representation is canonical and splitting based on some indicator seems... dodgy ?
update_unicode.py, line 512 at r3 (raw file):
size = len( code_points ) original_table = '{{' original_size = 0
This section looks dense and liable to errors when changing. Could we present it as generalised data, then run an algorithm on it. Something like
table = {
'original': { 'output': '{{', 'size': 0, 'converter': CppChar },
'normal': { ... },
'is_letter': { 'output': '{{', 'converter': CppBool }
}
for t, d in iteritems( table ):
entry = code_point[ t ]
d[ 'output' ] += d[ 'converter' ]( entry ) + ','
d[ 'size' ] += max( CppLength( entry ), d[ 'size' ] )
Does that a) work, b) seem easier to maintain ?
I think it would be easier to review, as this is currently quite repetitive, which can lead to difficulty in spotting errors.
Introduce RawCodePointArray for FindCodePoint to iterate of a continous array instead of an array of structs. This also allows the arrays in RawCodePointArray to use char[] instead of const char* and thus avoids 12MB of relocation data on linux.
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.
Reviewable status: 1 of 2 LGTMs obtained
update_unicode.py, line 51 at r3 (raw file):
Previously, puremourning (Ben Jackson) wrote…
I wonder if we should really use a bitset here. A std::array of bools is a large overhead of unused bits. For an array of 10,000 bools:
bash-3.2$ ./array Array: Size: 10000 Bitset: Size: 1256
Possible early optimisation, but this would also have better cache coherency as well as saved padding.
It's not 10.000, it's 132.624.
Yes, I used .
to separate thousands, sue me!
I'm trying it out.
update_unicode.py, line 501 at r3 (raw file):
Previously, puremourning (Ben Jackson) wrote…
I think this could benefit from a comment explaining what it does. It would seem to me that the len( bytes() ) representation is canonical and splitting based on some indicator seems... dodgy ?
Done, though wording might not be the best. Tell me if you want it reworded.
update_unicode.py, line 512 at r3 (raw file):
Previously, puremourning (Ben Jackson) wrote…
This section looks dense and liable to errors when changing. Could we present it as generalised data, then run an algorithm on it. Something like
table = { 'original': { 'output': '{{', 'size': 0, 'converter': CppChar }, 'normal': { ... }, 'is_letter': { 'output': '{{', 'converter': CppBool } } for t, d in iteritems( table ): entry = code_point[ t ] d[ 'output' ] += d[ 'converter' ]( entry ) + ',' d[ 'size' ] += max( CppLength( entry ), d[ 'size' ] )
Does that a) work, b) seem easier to maintain ?
I think it would be easier to review, as this is currently quite repetitive, which can lead to difficulty in spotting errors.
Yes, it works and it is much nicer to look at.
I've used table.items()
for two reasons: a) I didn't want to pull in python-future dependency, b) the script was already python3 only.
On the other hand, I think, this makes the script take a little longer to execute.
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.
Reviewable status: 1 of 2 LGTMs obtained
update_unicode.py, line 538 at r4 (raw file):
d[ 'output' ] = d[ 'output' ].rstrip( ',' ) + '}},' if t == 'combining_class': d[ 'output' ] = d[ 'output' ].rstrip( ',' )
will this ever do anything, as you previously added '}}' to the end ?
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.
Reviewed 1 of 3 files at r1, 1 of 1 files at r3, 1 of 1 files at r4.
Reviewable status: complete! 2 of 2 LGTMs obtained
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.
Reviewable status: complete! 2 of 2 LGTMs obtained
update_unicode.py, line 51 at r3 (raw file):
Previously, bstaletic (Boris Staletic) wrote…
It's not 10.000, it's 132.624.
Yes, I used
.
to separate thousands, sue me!I'm trying it out.
I could get std::bitset
to compile but it broke tests. I vote for leaving this as is.
update_unicode.py, line 538 at r4 (raw file):
Previously, puremourning (Ben Jackson) wrote…
will this ever do anything, as you previously added '}}' to the end ?
I added }},
because the arrays in the initializer list need to be comma separated. Then on this line I remove the trailing comma, because the last array isn't followed by anything and can't have a trailing comma.
In other words, if you remove this line it won't generate valid C++.
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.
Reviewable status: complete! 2 of 2 LGTMs obtained
update_unicode.py, line 538 at r4 (raw file):
Previously, bstaletic (Boris Staletic) wrote…
I added
}},
because the arrays in the initializer list need to be comma separated. Then on this line I remove the trailing comma, because the last array isn't followed by anything and can't have a trailing comma.In other words, if you remove this line it won't generate valid C++.
erm,... go home ben, you're blind.
carry on.
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.
Reviewable status: complete! 2 of 2 LGTMs obtained
@zzbot r=micbou |
📌 Commit 046f37f has been approved by |
[READY] Use struct of arrays for static code_points object Introduce RawCodePointArray for FindCodePoint to iterate of a continous array instead of an array of structs. This also allows the arrays in RawCodePointArray to use char[] instead of const char* and thus avoids 12MB of relocation data on linux. This is another attempt of doing #1064. Table summary from [Michel's comment](#1140 (review)) <table> <tr> <th rowspan="2">Platform</th> <th colspan="2">Compilation time (s)</th> <th colspan="2">Library size (MB)</th> </tr> <tr> <td>Before</td> <td>After</td> <td>Before</td> <td>After</td> </tr> <tr> <td>Ubuntu 18.04 64-bit (GCC 7.3.0)</td> <td>26.56</td> <td>25.79</td> <td>19.59</td> <td>7.32</td> </tr> <tr> <td>macOS 10.14 (Apple Clang 10.0.0)</td> <td>29.16</td> <td>28.20</td> <td>7.09</td> <td>7.30</td> </tr> <tr> <td>Windows 7 64-bit (MSVC 15)</td> <td>30.62</td> <td>30.39</td> <td>7.86</td> <td>6.99</td> </tr> </table> <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/valloric/ycmd/1140) <!-- Reviewable:end -->
☀️ Test successful - status-appveyor, status-travis |
update_unicode.py, line 512 at r3 (raw file): Previously, bstaletic (Boris Staletic) wrote…
A little? It takes now 3 minutes and 23 seconds instead of 12 seconds for me; 17 times longer. I don't think this was worth the change. |
I didn't measure, but I do remember that I've sat through the script before. Now I do switch to my browser and I know it takes more than 2 minutes. Should we revert the changes in the script? |
Introduce RawCodePointArray for FindCodePoint
to iterate of a continous array instead of
an array of structs.
This also allows the arrays in RawCodePointArray
to use char[] instead of const char* and thus
avoids 12MB of relocation data on linux.
This is another attempt of doing #1064.
Table summary from Michel's comment
This change is