Fork me on GitHub
#clojure
<
2022-12-10
>
macrobartfast02:12:53

If one doesn’t have boot installed, is there a drop in substitute or approach? Someone’s repo calls for me to boot play <args>… and I don’t have boot installed (and installing it for this is not something I want to do right now).

hiredman02:12:19

No, boot tasks are written in clojure, and use code from boot to run

hiredman02:12:14

Play sounds like a task written for whatever code you are looking at, do you could try and look at the definition to see if it is a thin wrapper over some other code

macrobartfast07:12:22

Thanks! I’ll poke around and make it work… or I’ll go ahead and install boot.

Ulises MC05:12:50

Hi all! I have a question, I'm creating a game usnig Clojure 🙂 , it calculates each frame 60 times per second, that means the game state is updated 60 times per second (my state is a map). I have noticed that when creating a game, devs usually avoid creating lots of objects. Each Clojure function is a Java Object My code has this pattern in many places usnig both let and letfn:

(defn update-part-of-state [,,,]
  (letfn [(my-fn [part-of-state]
           ;; new-part-of-state
           ,,,)]
    (update-in state [:part :of :state] my-fn)))
So these functions are executed 60 times per second. My questions are: In this example, is my-fn created 60 times per second? I mean, it's a constant function, does Clojure make some kind of caching? I think that dividing the code in:
(defn my-fn [part-of-state]
  ;; new-part-of-state
  ,,,)

(defn update-part-of-state [,,,]
  (update-in state [:part :of :state] my-fn))
Is not elegant, since the second function only performs an update-in I could create a macro that writes the functions separated and let me write elegant code, but I don't want to waste time on it until I know it actually creates the same function each frame & I notice that the performance needs to be improved. Thanks in advance!

skylize06:12:26

> Is not elegant, since the second function only performs an update-in Small functions are great! Give it a good name that clearly describes the update, and then compose your smaller updates into larger ones.

3
p-himik09:12:52

A quick test with (compile ...) shows that it does indeed result in an object being created every time you call update-part-of-state. Probably because such an implementation is the simplest while still taking potential closures into account. But it shouldn't matter to you much by itself. JVM does a lot under the hood, more than you'd guess. So if you have performance concerns - first and foremost you should measure. I'm 95% certain that that update-in itself will take 100% of time as compared to a single new my_fn() that Clojure does where my_fn is a short-lived object with no members.

👍 1
1
Jan K15:12:09

I believe the function is compiled into a class only once. Then it gets instantiated for each call, but that's dirt cheap so no problem.

🆗 1
Ulises MC15:12:15

Ok, thanks guys! I think the problem with creating objects (even if they're cheap) is the GC, I'm using libGDX and running this code on Android, they recommend reuse and not to create short-lived objects, but until now, I haven't had any performance issues; just wanted to know more about Clojure.

p-himik16:12:42

If you don't have performance issues on your target platforms, then definitely don't use macros to "outline" such functions. :) There's no need to invent solutions for non-existing problems. Regarding that recommendation to reuse objects - I don't know Android at all, but maybe that recommendation is outdated on newer versions. I'd check with your target versions.

Jan K16:12:27

IDK about Android but modern JVMs and their GC are really well optimized for this. If you're worried about performance use some profiling tools, I'm sure you'll find juicier places to optimize.

Ulises MC16:12:53

@U2FRKM4TW Yep, as I previously said, I'd only make optimizations if needed :), maybe that recommendation is outdated since the docs are outdated. I'll read more about my target Android versions. @UCPGSBNQ4 totally agree.

andy.fingerhut17:12:13

I mean, the advice is well taken if your game tries to create a gigabyte of short-lived objects per second, as I would guess you would definitely notice performance issues in that situation. Creating a few kilobytes of short-lived objects per second is probably not noticeable performance-wise.

👍 1
Ulises MC17:12:29

Well, it's a bullet hell game (those with a spaceship and enemies that throw a lot of bullets, added a screenshot) I'll design a level to test the performance, right-now, it runs very good

Sam Ritchie17:12:22

You could also move the letfn outside the defn

Sam Ritchie17:12:43

Swap the order and avoid the new top level def