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

Initial version of osrparse backed by osucore (rust parser) #37

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

kszlim
Copy link
Owner

@kszlim kszlim commented Nov 7, 2022

approximately 14x faster in serial parsing, and N x that in multicore/batch mode.

@kszlim kszlim requested a review from tybug November 7, 2022 09:53
@kszlim
Copy link
Owner Author

kszlim commented Nov 7, 2022

after getting this merged, will change the CI to publish on release, probably makes sense to enable it for python as well

by osucore (written in rust), approximately
14x faster in serial parsing, and N x that
in multicore/batch mode.
Comment on lines -92 to 101
if mode is GameMode.STD:
if mode == GameMode.STD:
keys = Key(keys)
event = ReplayEventOsu(time_delta, float(x), float(y), keys)
if mode is GameMode.TAIKO:
if mode == GameMode.TAIKO:
event = ReplayEventTaiko(time_delta, int(x), KeyTaiko(keys))
if mode is GameMode.CTB:
if mode == GameMode.CTB:
event = ReplayEventCatch(time_delta, float(x), int(keys) == 1)
if mode is GameMode.MANIA:
if mode == GameMode.MANIA:
event = ReplayEventMania(time_delta, KeyMania(int(x)))

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the rust parser break is checks? is is the recommended way to compare enums in python, so this would have to be a breaking change if we're unable to replicate it in rust. Would much prefer (almost to the point of it being a requirement) if is checks worked as-is.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some ways I could get this to work, is checks will work if you directly compare IntFlags (ie. Mod.NoMod is Mod.NoMod) but will not work if one quantity is derived from an operation like (Mod.NoMod | Mod.Hidden) is (Mod.NoMod | Mod.Hidden), I might be able to figure out a way though it probably would get uglier, I'd have to precompute a whole bunch of mod combinations and make them const fields in rust, this would probably require some macros.

@@ -53,10 +66,10 @@ def test_is_perfect_combo(self):

def test_nomod(self):
for replay in self._replays:
self.assertEqual(replay.mods, Mod.NoMod, "Mod combination is wrong")
self.assertEqual(replay.mods.value, Mod.NoMod.value, "Mod combination is wrong")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this means the rust version doesn't support comparing intflag enums? That's pretty bad as well. I wouldn't want to use .value every time I did a mod comparison.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does, I just forgot to change this test back

@@ -350,7 +350,7 @@ class Replay:
rng_seed: Optional[int]

@staticmethod
def from_path(path):
def from_path(path, use_legacy_parser=False, header_only=False):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def from_path(path, use_legacy_parser=False, header_only=False):
def from_path(path, *, use_legacy_parser=False, header_only=False):

similarly for other static parsing methods.

Also unsure about exposing the legacy parsing at all. I think I'd prefer if we were entirely backed by osucore so we don 't have to maintain two versions.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, we could remove it, I just left it as an option in case there are parsing differences between the two methods, though the same backing objects are used between legacy and new now.

Comment on lines +28 to +30
install_requires=[
"osucore>=0.1.11",
],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is pulling from pypi right now, right? Having a separate package for the rust parser seems like bad style. Is this the intended path forward for the actual release? How would releasing a new osrparse version go? Would we have to build and release a new osucore version first, then bump the osucore requirement in osrparse and build and release a new osrparse version?

Ideally this would all be self contained in one pypi package and require only one build/release to release a new version.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I originally did this so that development could eventually be decoupled, but this might make sense if oscucore is really every used through osrparse

@kszlim
Copy link
Owner Author

kszlim commented Mar 20, 2023

Blocked by PyO3/pyo3#2384

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.

2 participants