Skip to content
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

Oracle: Optimize json parsing #3480

Merged
merged 1 commit into from
Dec 31, 2018
Merged

Conversation

ctrlaltca
Copy link
Contributor

Related Ticket(s)

Short roundup of the initial problem

Since the move from Mtgson2 to Mtgjson4, the json file size increased a lot. This resulted in increased parsing time in oracle, eg. on my mac from 5-10 second to over a minute. We are not even reporting a progress indicator to users.
Back in the Qt4 days, Qt had no native support for Json, so Cockatrice is embedding a 3rd party library called qt-json: https://github.com/qt-json/qt-json
Nowadays Qt5 has a native solution to parse Json, but it's so optimized for speed on small files that it doesn't handle big json files at all. I've tried to use it, but it end up with a too large document error.

What will change with this Pull Request?

While investigating the speed of the json library, I've found out that a couple optimizations could speed up the parsing by about 3 times. The original patch was found here: qt-json/qt-json#20
On my mac, the parsing time is reduced from 63 to 21 seconds.

I'm keeping this PR open a couple of days to investigate other possible optimizations.

@ZeldaZach
Copy link
Member

Note that I might move to GraphQL to only serve what you request

@ebbit1q
Copy link
Member

ebbit1q commented Dec 25, 2018

Isn't it faster to use regular expressions instead of indexof?

@tooomm
Copy link
Member

tooomm commented Dec 25, 2018

Parsing time is considerably faster now, which is awesome. 👍

Could you still look into implementing a progress bar for that part, please? @ctrlaltca

@ebbit1q
Copy link
Member

ebbit1q commented Dec 25, 2018

regular expressions are several orders of magnitude slower :/

@ebbit1q
Copy link
Member

ebbit1q commented Dec 26, 2018

Have you looked at using qjson ( http://qjson.sourceforge.net/ ) instead? We don't have to maintain a json parser ourselves.
Also qt's parser can't be used, see this bug: https://bugreports.qt.io/browse/QTBUG-58652

@ctrlaltca
Copy link
Contributor Author

Have you looked at using qjson ( http://qjson.sourceforge.net/ ) instead?

fab$ ./bin/cmdline_tester /Users/fab/Downloads/AllSets.json
Parsing of "/Users/fab/Downloads/AllSets.json" took 14377 ms

Looks like a good candidate, performance is comparable with the current implementation.

@ZeldaZach ZeldaZach merged commit 2621cc0 into Cockatrice:master Dec 31, 2018
@tooomm tooomm changed the title [WIP] Oracle: Optimize json parsing Oracle: Optimize json parsing Dec 31, 2018
@ctrlaltca ctrlaltca deleted the oracle_speedup branch January 9, 2019 20:59
ebbit1q added a commit to ebbit1q/Cockatrice that referenced this pull request Jan 10, 2022
the long type has different sizes across operating systems and should
not be used

in the timeline an overflow could occur if the width in pixels
multiplied by the total amount of milliseconds in the replay is larger
than 2^31 which is easy enough considering with only 500 pixels width
you'll reach this number with only 1.2 hours of replay (about 4 million
millis), note that this would be windows exclusive as *nix uses 64 bits

qt-json's own repo suggests using qt5's implementation instead, testing
revealed this is quite a bit faster, contrary to Cockatrice#3480

servatrice uses the qthread usleep function which used to be protected
but is now public

cockatrice is not compatible with qt4 and hasn't been for a while
ebbit1q added a commit to ebbit1q/Cockatrice that referenced this pull request Jan 10, 2022
the long type has different sizes across operating systems and should
not be used

in the timeline an overflow could occur if the width in pixels
multiplied by the total amount of milliseconds in the replay is larger
than 2^31 which is easy enough considering with only 500 pixels width
you'll reach this number with only 1.2 hours of replay (about 4 million
millis), note that this would be windows exclusive as *nix uses 64 bits

qt-json's own repo suggests using qt5's implementation instead, testing
revealed this is quite a bit faster, contrary to Cockatrice#3480

servatrice uses the qthread usleep function which used to be protected
but is now public

cockatrice is not compatible with qt4 and hasn't been for a while
ebbit1q added a commit to ebbit1q/Cockatrice that referenced this pull request Jan 10, 2022
qt-json's own repo suggests using qt5's implementation instead, testing
revealed this is quite a bit faster, contrary to Cockatrice#3480

after further investigation it became clear that this only works on the
qt version 5.15

we are not ready to end support for older versions of qt just yet so
maybe we can conditionally use the faster version instead?
ebbit1q added a commit to ebbit1q/Cockatrice that referenced this pull request Jan 10, 2022
the long type has different sizes across operating systems and should
not be used

in the timeline an overflow could occur if the width in pixels
multiplied by the total amount of milliseconds in the replay is larger
than 2^31 which is easy enough considering with only 500 pixels width
you'll reach this number with only 1.2 hours of replay (about 4 million
millis), note that this would be windows exclusive as *nix uses 64 bits

~~qt-json's own repo suggests using qt5's implementation instead, testing
revealed this is quite a bit faster, contrary to Cockatrice#3480~~ testing proved
this to not be compatible with older qt versions

servatrice uses the qthread usleep function which used to be protected
but is now public

cockatrice is not compatible with qt4 and hasn't been for a while
ZeldaZach pushed a commit that referenced this pull request Jan 16, 2022
the long type has different sizes across operating systems and should
not be used

in the timeline an overflow could occur if the width in pixels
multiplied by the total amount of milliseconds in the replay is larger
than 2^31 which is easy enough considering with only 500 pixels width
you'll reach this number with only 1.2 hours of replay (about 4 million
millis), note that this would be windows exclusive as *nix uses 64 bits

~~qt-json's own repo suggests using qt5's implementation instead, testing
revealed this is quite a bit faster, contrary to #3480~~ testing proved
this to not be compatible with older qt versions

servatrice uses the qthread usleep function which used to be protected
but is now public

cockatrice is not compatible with qt4 and hasn't been for a while
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants