Live data from Hacker News

A better streams API is possible for JavaScript

blog.cloudflare.com

161–167 of 167 posts

Re: A better streams API is possible for JavaScript

#161

Earlier quoted context omitted.

Brother, you are talking about one object for every byte . That is a madness. And often for no reason...you're copying or arranging bytes in lists anyway.

That's just how string iterators work in Javascript: one object for every byte. For now it's fast enough: https://v8.dev/blog/trash-talk . I'd put the GC overhead at around 10-15%, even with 20+ objects per byte when you add up all the stages in a real text processing pipeline. It's that cheap because the objects all have short lifespans and so they spend all their lives in the "tiny short-lived objects" memory pool…

One object for every UTF-16 code unit.

And yes, if that were the sole string interface, things would be very slow. String iterators are relatively less common.

Re: A better streams API is possible for JavaScript

#162

Earlier quoted context omitted.

The allocation of each object still has overhead though, even if they all live side-by-side. You get memory overhead for each value. A Uint8Array is tailor-made for an array of bytes and there’s a constant overhead. Plus the garbage collector doesn’t even have to peer inside a Uint8Array instance.

The engine can optimize all those allocations out of existence so they never happen at all, so it's not a problem we'll be stuck with forever, just a temporary inconvenience. If a generator is yielding values it doesn't expose step objects to its inner code. If a `for of` loop is consuming yielded values from that generator, step objects are not exposed directly to the looping code either. So now when you have a `for…

Can optimize in theory, or are you saying this is what JavaScript engines do today?

Re: A better streams API is possible for JavaScript

#163

Earlier quoted context omitted.

The engine can optimize all those allocations out of existence so they never happen at all, so it's not a problem we'll be stuck with forever, just a temporary inconvenience. If a generator is yielding values it doesn't expose step objects to its inner code. If a `for of` loop is consuming yielded values from that generator, step objects are not exposed directly to the looping code either. So now when you have a `for…

Can optimize in theory, or are you saying this is what JavaScript engines do today?

I don't think any engines today do this. It has not been worth spending the time optimizing because so few people are using iterators heavily.

Re: A better streams API is possible for JavaScript

#164

Earlier quoted context omitted.

That's just how string iterators work in Javascript: one object for every byte. For now it's fast enough: https://v8.dev/blog/trash-talk . I'd put the GC overhead at around 10-15%, even with 20+ objects per byte when you add up all the stages in a real text processing pipeline. It's that cheap because the objects all have short lifespans and so they spend all their lives in the "tiny short-lived objects" memory pool…

One object for every UTF-16 code unit. And yes, if that were the sole string interface, things would be very slow. String iterators are relatively less common.

Code unit, yeah. Isn't for/of over an array faster than an indexed loop these days? It's fast because they took the time to optimize it.

Re: A better streams API is possible for JavaScript

#165

Earlier quoted context omitted.

Interesting, thanks for the info, I'll do some reading on what you're saying. I agree, you're right about JS having issues with hiccups in the UI due to scheduling on a single process thread. Makes a lot of sense, cool that the garbage collector can run independently of the call stack and function scheduler.

OP doesn’t know what he’s talking about. Creating an object per byte is insane to do if you care about performance. It’ll be fine if you do 1000 objects once or this isn’t particularly performance sensitive. That’s fine. But the GC running concurrently doesn’t change anything about that, not to mention that he’s wrong and the scavenger phase for the young generation (which is typically where you find byte arrays bein…

Thanks for this. I was feeling similarly reading the original post.

I was trying to keep an open mind, it's easy to be wrong with all that's going on in the industry right now.

Thanks for clarifying some of the details back to what I was originally thinking.

Re: A better streams API is possible for JavaScript

#166

Earlier quoted context omitted.

I think we're having a completely different conversation now. The parent comment I originally replied has been edited so much that I think the context of what I was referring to is now gone. Also, I wasn't talking about building network layers, I was explicitly referring to things that use a network layer... That is, an application receiving streams of enumerable network data. I also agree with what you're saying, we…

Not the person originally replying, but as someone who avoids JS I have to ask whether the abstraction you provide may have additional baggage as far as framing/etc. Ironically, naively, I'd expect something more like a callback where you would specify how your input gets written to a buffer, but again im definitely losing a lot of nuance from not doing JS in a long while.

> I'd expect something more like a callback where you would specify how your input gets written to a buffer

Yes, and this is the way it works JS currently.

The reason I'm commenting is because it appeared folks were advocating to stop doing this (despite the fact it seems to work just fine).

Re: A better streams API is possible for JavaScript

#167

Earlier quoted context omitted.

I've been long on JS but never heard things like this, could you please prove it by any means or at least give a valid proof to the _around 15%_ statement? Also by saying _quick enough to not be noticeable_, what's the situation you are referring too? I thought the GC overhead will stack until it eventually affects the UI responsiveness when handling continues IO or rendering loads, as recently I have done some perf…

Yeah I mean don't take my word, play around with it! Here's a simple JSFiddle that makes an iterator of 10,000,000 items, each with a step object that cannot be optimized except through efficient minor GC. Try using your browser's profiler to look at the costs of running it! My profiler says 40% of the time is spent inside `next()` and only 1% of the time is spent on minor GCs. (I used the Firefox profiler. Chrome wa…

To me this is just "fake test". As I have said really world cases involves consistent IO loads and/or rendering loops, for example in my case I need to load tons of pixel data and decode them in works, then at the same time use canvas to render the decoded image and huge chunk of array data, they are real world high loads, there are tons of objects created during the process and way less counts than the "fake test", yet still optimizing the object counts made huge difference to the final performance.

Let's say talk about this in another more general case: virtual windowing. If anyone has tried to implement stuff and hit performance bottle neck and then find virtual windowing could help, it definitely involves two problems to solve, first is the UI responsiveness when more and more stuff got created and rendered, the object count usually should be way less than "10,000,000", yet still you could hit the wall.

I think I might be too negative about it, but I just want to share the real cases here.

Post reply on HN