cljs-dev

ClojureScript compiler & std lib dev, https://clojurescript.org/community/dev
2021-05-26T12:47:44.039600Z

not exactly cljs dev question: Curious if there were any attempts at improving transit-js performance? Looking at the source it seems like the algorithm recursively walks parsed JSON tree, which suggests that it could be more performant w/o recursion, since recursion is typically slower in JS engines (?).

emccue 2021-05-26T15:38:42.040300Z

@roman01la I don't think many people actually use transit-js

emccue 2021-05-26T15:39:20.041100Z

which makes sense, transit is only really popular in clojure and clojure is a relatively small community

emccue 2021-05-26T15:39:44.041600Z

so the pie slice of people who use transit and use JS is even smaller

emccue 2021-05-26T15:40:04.042100Z

which is to say it has likely been fast enough for the people who do use it

rakyi 2021-05-26T15:41:56.042900Z

transit-cljs depends on transit-js

emccue 2021-05-26T15:42:56.043100Z

^shove a foot in my mouth

2021-05-26T15:51:42.044Z

yeah, I’m referring to transit-js specifically, because it’s where the core of it is, transit-cljs is more of a wrapping library

2021-05-26T15:53:38.045700Z

the reason why I’m asking is because while parsing is fast, it’s still not fast enough in envs such as React Native or for real-time/streaming type of web apps, where updates are being consumed frequently and transit parsing periodically blocks the main thread

alexmiller 2021-05-26T16:00:56.046500Z

what other tech is fast enough in this scenario? (just looking to learn here)

alexmiller 2021-05-26T16:06:05.051700Z

it is likely a significant effort to implement the transit design in a streaming fashion, so I'm kind of wondering out loud if even that would be fast enough for the scenario you're asking about and whether there are known alternatives that meet the criteria (like, is streaming json sufficient?)

2021-05-26T16:06:41.052200Z

@alexmiller I don’t have an answer for this in a form of a working library, but in our case we are not sending custom data types over the wire except of UUID. @mfikes I’m wondering if a modified version of cljs-bean (that would recognize UUIDs) could make a difference?

2021-05-26T16:11:10.053900Z

@mfikes nice! but that’s only writing to transit, right?

mfikes 2021-05-26T16:12:03.054700Z

Oh, right.

2021-05-26T16:14:04.056100Z

@alexmiller I don’t think streaming parsing will be faster or even comparable to the current implementation. However would be interesting to see how performance would change with a non-recursive implementation, afaik JS engines are not that good at recursion, I might be wrong though.

alexmiller 2021-05-26T16:19:15.057Z

that seems like an overly generic conjecture with an absence of data :)

alexmiller 2021-05-26T16:20:21.057800Z

this is the sort of thing that may be true at a point in time, then becomes conventional wisdom, but the enormous performance pressures on js engines completely invalidate over time. but I don't have any clue either way

👍 1
emccue 2021-05-26T17:12:36.058400Z

@roman01la strawman - try and find a json parser that is fast enough for your use case

emccue 2021-05-26T17:13:01.058800Z

like parse the data from your server as json, then insert mock data into the app

emccue 2021-05-26T17:14:14.060200Z

that would give a jumping off point to figure out where transit-js can improve / there is room for a different impl of the spec

dnolen 2021-05-26T18:39:07.061300Z

@roman01la it would be interesting to figure out if that it would be faster but I think it would be a significant amount of work

dnolen 2021-05-26T18:39:15.061600Z

the amount of tuning that went into transit-js is non-trivial

dnolen 2021-05-26T18:40:09.062500Z

the other thing is that transit-js is currently unsuitable for streaming - so dropping the recursion seems a bit dubious to me vs. just doing something better (suited)

👍 1
dnolen 2021-05-26T18:42:01.063600Z

back when I worked on none of the JS streaming parsers seemed practical - that assumption may not be true anymore

dnolen 2021-05-26T18:42:59.064500Z

it also of course leads to a different API which isn't necessary in many circumstances and a big pain

dnolen 2021-05-26T18:44:20.065700Z

i.e. the streaming parsers - one big problem is that you need a sensible event loop thing but a lot of JS environment aren't going to give you that out of the box

dnolen 2021-05-26T18:51:12.065900Z

https://cognitect.github.io/transit-tour/

dnolen 2021-05-26T18:51:31.066300Z

it's an old version of transit but there haven't been any performance related changes since the first version

dnolen 2021-05-26T18:52:37.067200Z

at the bottom are timings, it's interesting to check these between browser

dnolen 2021-05-26T18:52:43.067500Z

the gap has only decreased over time on all engines

dnolen 2021-05-26T18:53:35.067700Z

Firefox used to be 2X slower

dnolen 2021-05-26T18:54:42.068400Z

but using the latest FireFox converting 53K of JS is only 0.10 ms more than the equivalent payload of JSON (i.e. duplicated keys)

dnolen 2021-05-26T18:54:58.068700Z

so key caching cuts the JSON parse time in half

dnolen 2021-05-26T18:55:15.068900Z

and then you need another full walk

dnolen 2021-05-26T18:56:17.069300Z

but the end result is only slightly slower than non-cached key JSON

dnolen 2021-05-26T18:57:01.070100Z

it's true that in React Native you don't get native compilation so numbers there would be interesting - but I'm pretty skeptical about the streaming web apps

dnolen 2021-05-26T18:57:22.070600Z

unless there's good benchmarks to show the benefits of a JS streaming parser over just paginating the result or whatever