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

Dispatching channels with multiple message types #90

Closed
limx0 opened this issue Mar 14, 2022 · 5 comments
Closed

Dispatching channels with multiple message types #90

limx0 opened this issue Mar 14, 2022 · 5 comments

Comments

@limx0
Copy link

limx0 commented Mar 14, 2022

Hi @jcrist

I'm using msgspec to decode some JSON from a channel that sends multiple message types, and am wondering how best to dispatch these messages to msgspec (please close if this is out of scope or you don't have any opinion).

I observe (roughly) the following times for a couple of methods I've tried, and they're pretty much ordered from fastest to most correct:

raw = b'{"Type":"Trade", "Symbol":"AAPL", "LastTradedPrice":100}'

# startswith - fastest, but requires Type to be at the beginning of JSON
%timeit raw.startswith(b'{"Type":"Trade"')
178 ns ± 0.0241 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)

# in - slightly slower but more correct
%timeit b'"Type":"Trade"' in raw
430 ns ± 2.78 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)

# msgspec - most correct, parsing explicit Literal
class MessageType(msgspec.Struct):
    MessageType: Literal["Trade", "Quote", "Heartbeat"]

%timeit _ = msgspec.json.decode(raw, type=MessageType)
1.2 µs ± 0.707 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)

# JSON decoding - Another option?
decoded = msgspec.json.decode(raw)
2.89 µs ± 15.7 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

Obviously theres standard performance trade offs here; but I wonder if you've thought about handling this in msgspec or have any other more correct but also performant suggestions?

Thank you again for this wonderful library!

@limx0
Copy link
Author

limx0 commented Mar 14, 2022

I should also note I'm willing to PR / test something if you have any suggestions. I'm not comfortable in C, but am reasonably comfortable writing some Cython.

@jcrist
Copy link
Owner

jcrist commented Mar 15, 2022

Hi @limx0, if I understand correctly you're looking to dispatch the type of the message to one of several types based on the value of a Type key in the message? If so, have you seen https://jcristharif.com/msgspec/structs.html#tagged-unions? This is exactly what that feature is for.

@limx0
Copy link
Author

limx0 commented Mar 15, 2022

Yes thats correct; and this looks exactly like what I am after. Apologies for not reading the docs correctly!

drawing

@limx0 limx0 closed this as completed Mar 15, 2022
@jcrist
Copy link
Owner

jcrist commented Mar 15, 2022

No worries! Is the documentation clear enough? Is there a different place you looked for information like this? There might be a better way to organize the docs.

@limx0
Copy link
Author

limx0 commented Mar 15, 2022

I think the docs are clear now that they're been pointed out to me. Probably what I was looking for was something along the lines of "processing/handling multiple types in a stream" or something to that effect; Tagged Unions didn't jump out at me as what I was after.

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

No branches or pull requests

2 participants