-
Notifications
You must be signed in to change notification settings - Fork 3.3k
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
Go runtime performance fixup #2916
Conversation
Further investigation shown real problem is GC and pointers: https://syslog.ravelin.com/further-dangers-of-large-heaps-in-go-7a267b57d487 |
@dmitrys99 Is it in a viable state for testing? I see Golang performance issues as well. |
I added several commits, now compilation goes significantly faster. You can try to test with this PR, it does things faster, but not as Java runtime does. |
@dmitrys99 I have tested it and it seems to cut 30% from the parsing time (in my case). |
@parrt Can this be pulled into master? I can confirm significant speed up and maybe other people can join the effort. |
@davesisson I think you're the Go guy. can you take a look? |
This pull makes it much better, but if there is a Golang expert, I would like some opinion why it is spending so much time in garbage collector? Can garbage collector be disabled during the parsing and memory cleared once after parsing?
|
I tried to turn off GC, it does not help, unfortunately. It consumes about 7 GB of data on test case. |
@dmitrys99 I think the problem is not the pointers, but a lot of memory allocation on heap. Each of these calls allocates memory and thus creates another item for the garbage collector to handle:
I did modification like this (basically allocating memory in bulk):
Ant it cut another 25% off the time on top of your patch, but now I leak memory for some reason. Seems like |
Hm, maybe it does not leak but has slightly larger memory use. You can check if it works for you better. |
Thank you for your attempt to fix the issue! It might be a solution yet I see couple of drawbacks.
The real solution should be based on knowledge of Antlr internals. I have questions, which I have no idea how to answer.
Knowing this information will allow us to model cleanup procedure in Go in a way it can be performant yet be different from Java's way. Since @parrt is on the thread, may be this questions are to you. |
I think it would work with several parsers running parallel, but nodes from them would mix into the single allocated memory and the memory would be released only when all nodes from all parsers in it would be released. It could be revoked that memory would be allocated in the parser and all nodes in such block would belong to the same parser. I was basically testing different approaches so it is not a perfect solution.
I agree that knowledge of Antlr internals and behaviour of the golang garbage collector behaviour is the key here. |
@jjeffcaii could you take a look if it has already been fixed by your improvements or it's another problem? |
They look similar, but I'm not sure, I think they are all aim to resolve the hash problem, the modification of murmur hash is the same. |
I have tested it with 4.9.3. On my side performance increase about 2 times (21 sec vs 49 sec). This is a good improvement. But my previous experience shows there might be 7 times. I'll try to combine these two approaches and see. |
I have tested test case from #2888. There are times:
So, while there is an improvement, I still think the problem with Golang target if fundamental. Please take a look to #2888 (comment), there is an explanation. Moreover, performance is unstable (previously I got better timing), because it depends on Go GC implementation. I see no other means except Go target redesign. |
It seems like this MR should had to be merged instead of the newest one. |
@jcking Could you take a look at this and see how we might combine efforts here on performance? @dmitrys99 could you Provide the test rig that checked performance? |
@parrt It might be worth someone checking the performance against the current dev branch after my performance fixes. I suspect that this is now fixed as the need for garbage collection has been improved drastically. We can then close this issue. |
I did. I can confirm issue test executes 1.6 s on |
Very interesting to hear how did you do that! |
I’ll test it myself as well then. It should be milliseconds I think.
There were many bugs and a few bad design choices. Sets, hashing,
conflicting alt resolution, LL(*) resolution didn’t work. There may yet be
more. And I can see some future improvements.
The hashing now reflects Java, but uses Go generics for collections.
There’s also a PR waiting that reduces memory allocations and a couple of
extra collections that might be worth redoing.
I’m just going to fix all outstanding bugs first.
…On Mon, Aug 22, 2022 at 19:26 Dmitry Solomennikov ***@***.***> wrote:
@parrt <https://github.com/parrt> It might be worth someone checking the
performance against the current dev branch after my performance fixes. I
suspect that this is now fixed as the need for garbage collection has been
improved drastically. We can then close this issue.
Very interesting to hear how did you do that!
—
Reply to this email directly, view it on GitHub
<#2916 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAJ7TMDPSAUUNUJ5J6J5L2DV2NPXHANCNFSM4RS7UZNQ>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
Should we close as @jimidle's PRs fixed performance or is this still needed? |
Closed. Development goes to #2888 |
Main performance issue in Go runtime comparing to Java runtime is absence of
hashCode()
method in Go world. It is emulated usinghash()
method which is called directly or indirectly significant amount of times. But instead of returning precalculated hash it actively calculates actual hash on each call. This leads to significant performance degradation.This PR reduces time required to calculation to about 7 times.