This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-08-23
Channels
- # babashka (4)
- # beginners (46)
- # biff (64)
- # calva (34)
- # cider (29)
- # cljdoc (12)
- # cljs-dev (16)
- # clojure (42)
- # clojure-australia (2)
- # clojure-china (1)
- # clojure-europe (35)
- # clojure-filipino (1)
- # clojure-hk (1)
- # clojure-indonesia (1)
- # clojure-japan (1)
- # clojure-korea (1)
- # clojure-my (1)
- # clojure-nl (1)
- # clojure-norway (6)
- # clojure-sg (1)
- # clojure-taiwan (1)
- # clojure-uk (4)
- # clojurescript (3)
- # core-typed (3)
- # cursive (5)
- # datalevin (3)
- # datomic (23)
- # hyperfiddle (92)
- # joyride (8)
- # juxt (3)
- # malli (1)
- # nbb (44)
- # pathom (10)
- # portal (3)
- # rdf (1)
- # reitit (10)
- # shadow-cljs (60)
- # sql (12)
Hi everyone, I was just wondering if it's normal for it to take almost 10 (actually 4) minutes to start up a cider repl?
Depends. Is it a fresh start and it fetches dependencies? Also there are might be several places in clojure project that gets invoked during repl start: https://github.com/technomancy/leiningen/blob/github/sample.project.clj#L378 option in project.clj or user.clj namespace somewhere in project's sources
Normal? Absolutely not. Possible? Yes, in some cursed situation.
old clojure (before 1.10.1) may have pretty slow startup with new JVM's https://insideclojure.org/2019/03/23/journal/ that is the only case that I can imagine a 10min startup (or a pretty slow machine)
Hah okay good to know! Yeah I just see "clojure is slow to start " but didn't have any specifics on what that meant. I'll try to figure it out and will ask more questions here! (On clojure 1.11 btw)
btw: it is not due "clojure initialization" it is probabliy: • lein plugins loading • project loading thing into classpath during the REPL initialization i personally consider both a bad practice.
as a reference, the project I'm working with gets me from cider-jack-in to when I can type something at the repl in under 6 seconds in an old laptop from 2013. And it is loading some extra nrepl middleware
> Any tips for timing and debugging the startup process? do you have a user.clj file?
oh, if you are on lein I think it will also load whatever ns you have on :main if iirc. My times were using clj and not loading anything
oh, then it shouldn't load anything at startup, which is more weird
:repl-options { :init
might contain expression that gets executed during repl start up. For example the project I'm maintaining at the moment takes ~4 minutes to run a repl just because during :init it does some heavy lifting ensuring development database state
For context if I do anything with lein at all (like lein show-profiles) it takes several minutes
another thing you can try is :
JVM_OPTS=-verbose:class lein repl | grep your_project_top_ns
passing -verbose:class to the jvm will make it log every class it is loading, so if you see your ns there, they are being loaded just by doing lein repl
you need underscores in your_project_top_ns if it is your-project-top-ns
after you figure out what of your ns are being loaded, I would search in them for top level expressions that are evaluated and can take a long time, like :
(def thing (download-big-file))
If you're on an arm mac, are you sure that you've installed the correct architecture jvm? you might be emulating x86 by accident?
I wrote a blog post on this topic a while ago: https://blog.flowthing.me/clojure-repl-start/ One thing that article only touches on, though, is that Clojure starts noticeably faster on newer Java versions (17+ or so).
Thanks everyone, here's where I'm at. Btw it turns out my original assertion of 10 minutes to start the repl was an exaggeration. In reality it's around 3-4 minutes.
• time lein classpath 71.16s user 62.80s system 96% cpu 2:19.04 total
• using JVM_OPTS=verbose
showed another 40 seconds of loading internal libraries. There were some things that looked like they took ~5 seconds
• Cleared out everything in my user.clj
and the repl still took 3-4 minutes to start.
• @U0P0TMEFJ I have an M1 so it's possible there's an issue here. How can I check?
• I probably won't mess with the java version just yet since I'll be out of sync with our production systems
> I have an M1 so it's possible there's an issue here. How can I check?
exec this command with running repl:
ps aux | grep -f <(fuser /usr/libexec/rosetta/runtime 2>/dev/null | xargs -n1)
you will see a list of processes started under rosetta
I think file $(which java)
might also work?
λ file $(which java)
/usr/bin/java: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64e:Mach-O 64-bit executable arm64e]
/usr/bin/java (for architecture x86_64): Mach-O 64-bit executable x86_64
/usr/bin/java (for architecture arm64e): Mach-O 64-bit executable arm64e
Perfect, thank you! (here's mine)
file $(which java)
/usr/bin/java: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64e:Mach-O 64-bit executable arm64e]
/usr/bin/java (for architecture x86_64): Mach-O 64-bit executable x86_64
/usr/bin/java (for architecture arm64e): Mach-O 64-bit executable arm64e
So many ways to serialise stuff. I can use Transit, Fressian, Nippy.
I just want to serialise some data before putting it into a RabbitMQ using langohr (my map includes a bytearray).
I tried Nippy and Transit and both worked fine. I couldn't get Fressian working because it gives me HeapByteBuffer
which there seems to be no strait-forward way to convert that to a bytearray which is what langohr needs.
What is the different between these libraries other than the fact that they all provide different outputs:
• nippy gives me a bytearray
• Transit gives me a stream
• Fressian gives a HeapByteBuffer :face_with_raised_eyebrow:
The most important factor to me is if there might be breaking changes in the serialisation process after updating a library. I remember some painful migrations when I used nippy. Nothing like that should happen with transit because of the way it is designed. And I can't say anything about fressian because I never used it.
pr-str doesn't work well with bytearray, does it?
unless with custom print-method
The question isn't asking about serializing byte arrays, but wants to serialize to a byte array
> my map includes a bytearray I'm believing that there is bytearray to serialise
Transit is actually a family of formats, the most common one is encoded as json, which also has issues with binary data
Thanks both. I have already tested nippy and transit+msgpack. Both are working fine. But I wanted to try them all to find which is most convenient. Honestly nippy was easiest to implement because it gives me a byte array which langohr accepts. Fressian gave me a HeapByteBuffer which I have no idea what to do with that.
> Transit write to a java.io.bytearrsyoutputstream Yes but I can convert this to a byte array by simply calling .toByteArray on it
yes Fressian works too when calling .array
on the HeapByteBuffer. Thanks!