This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-09-14
Channels
- # announcements (40)
- # aws (9)
- # babashka (21)
- # beginners (75)
- # calva (56)
- # chlorine-clover (1)
- # cider (12)
- # circleci (1)
- # clj-kondo (7)
- # cljsrn (13)
- # clojars (3)
- # clojure (171)
- # clojure-dev (11)
- # clojure-europe (64)
- # clojure-nl (11)
- # clojure-spec (6)
- # clojure-uk (9)
- # clojurescript (31)
- # conjure (1)
- # cursive (7)
- # datascript (7)
- # datomic (9)
- # emacs (4)
- # fulcro (65)
- # introduce-yourself (1)
- # jobs-discuss (7)
- # kaocha (7)
- # lsp (39)
- # missionary (5)
- # off-topic (54)
- # pathom (10)
- # re-frame (6)
- # shadow-cljs (110)
- # tools-deps (41)
Todays little nugget. If you want peformant code, you need to write specific code.
I suggested a patch for CLJS for removing dead code in println
in the name of "doing less is faster". But it wasn't well received because "the golden rule is to not change" or something 😁
I think the Clojure core team is often a bit too dogmatic about this kinda stuff. Surely you can rewrite internal logic or refactor code in such a way that it doesn’t bother anyone. Isn’t that the point of having abstractions?
And, yes, I’m looking at a very specific piece of Javascript code which could/should be a lot faster than it is.
> the golden rule is to change nothing - unless we're adding something or fixing a bug
I guess the rules differ between your app code and the language itself, where any misstep is kind of disastrous
You could also argue that dead code is confusing and doesn't contribute to understandability
haha I concur. I've made a lot of optimizations in SCI to do less but the code became way more boilerplatey
Two great arguments
Good Morning!
Those miliseconds that I’m waiting are miliseconds off of my life! 🙂
Actually, the same for dead/confusing code. The time I spend rummaging around spaghetti is time I’m not doing productive and/or enjoyable stuff
The customer project I’m currently at had a strict “Readability before Performance” policy in place. Now, two years later, it has grown a lot and 40% of the bugs I get are performance-related 😕
Hopefully, you are then able to easily find the relevant parts of the code, with the high readability aspect in place 🙂
It’s okay I guess. Vented with an article on shortcomings of enterprise software projects last week, which took some beatings in the comments. Code quality and architecture in big project-style setups is insanely hard, imho.
It just is, isn’t it?
Everything looks good in example code 🙂
Big projects accrue more or less undocumented compromises en masse, and even if you have sane conventions for everything you’re doing, it can be hard to keep them, or enforce them. It can make you feel a bit hopeless at times. And it can make you love deleting cruft; I sure do!
and there are some low hanging fruits to always reach for, for decent performance without trading readability
It’s the tradeoff, like everywhere. We try to aim for a readable, high level orchestration, then it doesn’t hurt if the specialized code is harder to understand. Almost like a DSL for your problem… :thinking_face:
Here’s the code I was unfortunate enough to read: https://github.com/jashkenas/backbone/blob/master/backbone.js#L478
Also, this function is generic for create/update/delete so it has to cater for all of them.
I’d argue that most of the time when you call set
you know if you’re doing a create, update, or a delete.
And the convenience you get from being able to call set("foo", "bar")
or set({"foo": "bar"})
is neglible.
Could it be that it was hard to update the call sites when they changed their mind about the signature?
I think the Clojure core team is often a bit too dogmatic about this kinda stuff. Surely you can rewrite internal logic or refactor code in such a way that it doesn’t bother anyone. Isn’t that the point of having abstractions?
The issue was around flush
being a no-op:
https://github.com/clojure/clojurescript/blob/aec9f0c576ac6b11d3e30e79553c8ebe67bf0f73/src/main/cljs/cljs/core.cljs#L10218
And then this is unnecessary:
https://github.com/clojure/clojurescript/blob/aec9f0c576ac6b11d3e30e79553c8ebe67bf0f73/src/main/cljs/cljs/core.cljs#L10387
Probably minor, but getting rid of flush altogether would have been my preference.
Looking closer into it, the newline
function doesn't seem to be used anywhere either, so it's a very minor issue. The code just confused me since I thought flush
was a real thing in CLJS, but it isn't, so the *flush-on-newline*
dynamic var is nonsense as well.
I find "the golden rule is to change nothing - unless we're adding something or fixing a bug" very interesting. I favour maintainability by trying to make code understandable to myself and others. I've been comfortable making changes for maintainability because I feel somewhat protected by my unit tests. But... these "guard rails", as Rich has argued, might offer a false sense of security. If you change something you do risk breaking something. An interesting perspective.
I personally think that's a gap in your test suite but yeah, different perspectives.
I've made an optimization in SCI which turned out to cause a bug but I was happier to have discovered this than not having done the optimization at all since I now have a stronger test suite