5 ms·
No. Doing UI in JavaScript shouldn't make any noticeable difference. I say that as someone who hates JavaScript and doesn't think it should be used for anything
by ragnese 3y ago
No. Doing UI in JavaScript shouldn't make any noticeable difference. I say that as someone who hates JavaScript and doesn't think it should be used for anything, really.
But, UI apps are long-running, and interactive. There's no real "throughput" or anything like that to be concerned with.
The problem is precisely with the crowd that believes that ALL optimization is premature--or rather that code styles that I would consider pessimization is good. For example, in JavaScript, it's considered hip and "functional" to have a local variable that's an array, and instead of mutating it, programmers will string together five calls to `map`, `filter`, etc, making a bunch of temporary copies and iterating the data five times instead of once.
Writing JavaScript with what I've heard called "mechanical sympathy" does not have to be slow at all.
- 6510 3y agoput the nice looking calls to `map`, `filter`, etc in a comment then rewrite it with a for loop under it.
- ragnese 3y agoThat's a pretty nice suggestion. Honestly, though, the expanded for loop implementation is never really that complicated in practice.
- shadowgovt 3y agoIt depends what you're aiming for. For accuracy, map and filter make it impossible to fall off the bounds of your iteration. While it would certainly be nice if the runtime could do that faster, slow + correct is often (not always) better than fast + broken. (There are languages that make fast + correct easier. Unfortunately, JavaScript isn't really one of them).
- ragnese 3y agoJavaScript has `for-of` syntax for iterables, so you won't go out of bounds, regardless.
- ndriscoll 3y agoChained folds (map, filter, etc.) immediately within the same expression really should be easy to optimize, but even if the compiler doesn't do that, if the library provides those methods as operations on iterators, then an unoptimized version should only cause redundant loop counters and a single extra array allocation whenever you materialize it. So the array temporaries are a bad implementation/design choice. Scala has functional web frameworks that have no problem doing 100k+ requests per second on older mid tier desktop hardware, and while that's slow compared to a good mutable, imperative C implementation, it's fast enough that obviously functional programming per se is not the reason for perceived UI slowness.
- ragnese 3y agoI'm certainly not against chaining combinators in general. In fact, I love functional programming and I enjoy Scala. I'm only specifically criticizing it in JavaScript and other languages that decided to import functional programming features onto eager collections. Scala's standard collections are implemented as persistent collections, so the overhead for each combinator call is small, and could even be optimized by the compiler. JavaScript doesn't have a compiler, so the best you could hope for is a JIT optimization, but even that's impossible for several reasons related to the dynamic nature of the language. As an aside, I sometimes like to shit on Java, but the language is very well engineered, despite its "original sins" that make me hate it. When Java decided to import functional programming niceties, they didn't just tack `map` and `filter` onto `Collection<T>`. They added the whole `Stream` API which does the best possible thing given what the language already was.
- jerf 3y ago"Chained folds (map, filter, etc.) immediately within the same expression really should be easy to optimize" In a pure functional language they are. In a non-functional language with mutation it is much more challenging. Map functions are unconstrained in Javascript which means they can do anything they like with regards to breaking optimization. This is generally why I'm down on the whole "chain maps and filters" style of programming in languages that aren't designed for it. You are paying more than you may realize if you've never profiled your code and compared. In languages that are designed for it and have the ability to optimize it, by all means, go for it. The other thing you have to remember is that JITs are time-constrained as optimizers go. They have the advantage of access to real run-time information about how things are being used, but they also have very, very tight time budgets; on the whole the time budget's problems seem to dominate the knowledge advantages. The profiler is not allocated a lot of time to prove that a given function is pure and it's OK to synthesize a composed function rather than run two maps. I don't even know if any JS engine is smart enough to try that. (Input from anyone who knows welcome, I'd be interested to hear either way.)