tools-build

flowthing 2023-10-23T09:01:22.688759Z

Working on migrating from Leiningen to tools.deps/tools.build. clojure.tools.build.api/uber takes a very long time to finish:

(time (build/uber
       {:class-dir class-dir
        :uber-file "target/server.jar"
        :basis basis
        :main 'foo.main}))
"Elapsed time: 296066.973708 msecs" ; ~5 minutes
nil
Compared to lein uberjar:
Ξ» time lein uberjar
...

________________________________________________________
Executed in   44.17 secs    fish           external
   usr time   20.59 secs    0.10 millis   20.59 secs
   sys time   11.67 secs    1.56 millis   11.67 secs
(Which includes two JVM startup times, AOT compilation, nREPL & Leiningen overhead, etc.) Is this expected?

flowthing 2023-10-23T09:02:13.549159Z

Actually, I wonder if it might be the old corporate antivirus software interference story once again...

2023-10-23T10:47:55.351559Z

have you tried https://github.com/clojure-goes-fast/clj-async-profiler on it? I think wrapping that in a prof/profile instead of time should tell you where all that time is going

flowthing 2023-10-23T10:54:42.648259Z

I haven't yet. I'll give that a try. πŸ‘

flowthing 2023-10-23T11:19:35.811889Z

flowthing 2023-10-23T11:24:58.548089Z

The resulting uberjar is 29M, so nothing out of ordinary.

2023-10-23T11:29:11.652159Z

yeah I don't see anything that catches my attention there πŸ€”

2023-10-23T11:35:53.211089Z

I don't see the GC activity on the graph, was there any?

flowthing 2023-10-23T11:37:13.353179Z

I don't know. I'm not very adept at using clj-async-profiler. πŸ™‚ Here's the HTML version if you want to take a look.

2023-10-23T11:41:06.458829Z

that small thing in yellow on the right shows GC and Hotspot compilers activity, but is very small

flowthing 2023-10-23T11:41:29.475189Z

Right, thanks. πŸ‘ At least I learned something new. πŸ™‚

flowthing 2023-10-23T11:41:49.096829Z

Maybe I'll try strace or whatever the macOS equivalent is...

2023-10-23T11:43:22.401089Z

yeah could be a good idea, if you grep out all those pesky futex calls

flowthing 2023-10-23T11:44:21.189959Z

Unless I'm foiled by System Integrity Protection...

2023-10-23T11:47:26.788499Z

or you can also run the profiler for the lein process and compare the flamegraphs? maybe there is something there. You can download async profiler https://github.com/async-profiler/async-profiler, unzip that into a folder, and then what I do is run ./profiler.sh -e cpu -d SECONDS_TO_SAMPLE -f /tmp/flamegraph.html YOUR_LEIN_PID

2023-10-23T11:47:58.868049Z

so you can run that against any java process and it will give you the flamegraph

flowthing 2023-10-23T11:48:21.710939Z

Thanks, I'll give that a try if the dtrace path is a dead end. πŸ‘

πŸ‘ 1
seancorfield 2023-10-23T14:36:34.639259Z

I can't remember whether Leiningen explodes all the JARs on the classpath into the target/classes folder before building the uberjar -- I suspect it doesn't -- so if you have antivirus software checking every new file created, tools.build.api/uber is going to be badly affected since it explodes JARs and copies everything into the target tree first, then assembles the JAR from all those files... lots of file activity. (depstar originally did that in two passes but I switched it to copy everything directly into the JAR, exploding JARs on the classpath only in memory -- made it run over 2x faster every without virus checking)

flowthing 2023-10-23T15:07:08.704069Z

That definitely sounds plausible, thanks. πŸ‘πŸ»

salam 2023-10-23T16:18:44.608389Z

We use https://github.com/tonsky/uberdeps (which β€œdoes not unpack intermediate JARs on disk.”) in our tools.deps projects. The poor performance (even on a Mac without antivirus software) of tools.build.api/uber is the only reason that’s preventing us from switching to it.

πŸ™ 1
flowthing 2023-10-23T16:38:11.149209Z

I see, thanks. I used to use uberdeps before tools.build was a thing, but I think I’ll give it a try to see how it compares. πŸ‘πŸ»

πŸ‘ 1
flowthing 2023-10-23T17:02:59.959449Z

https://clojurians.slack.com/archives/C02B5GHQWP4/p1640887876383200?thread_ts=1637254945.235200&cid=C02B5GHQWP4 this sounds like the exact same issue.

seancorfield 2023-10-23T18:31:10.499049Z

Cool. Can you get it configured to ignore certain folders? I've generally found antivirus software to be pretty problematic for developers in any situation where code is getting compiled or build systems are shuffling a lot of files around...

flowthing 2023-10-23T18:32:04.967249Z

I believe there was an opportunity to do something like that at my previous job, but it used a different AV program... I'll have to ask around.

flowthing 2023-10-23T19:02:11.306129Z

Yeah, I can reproduce the issue with e.g. https://github.com/seancorfield/usermanager-example. I'm on a pretty beefy MacBook Pro M2, and (b/uber (uber-opts {})) takes over a minute, whereas on a much less capable Linux box (with no corporate malware) it takes ~5 seconds.

seancorfield 2023-10-23T20:09:25.269099Z

Thanks for confirming that @flowthing -- Hopefully, you can address the situation with your IT team because I would expect that A/V tool to slow down a lot of software development tasks.

πŸ™ 1
flowthing 2023-10-24T05:57:49.561129Z

Just one final comment for posterity, in case anyone finds this thread via Slack search or something: I added exclusions for the folders I use for dev via Virus & threat protection settings Β» Manage settings Β» Add or Remove Exclusion... in Microsoft Defender (which our corporate policy luckily allowed), and that made a big difference: building an uberjar via clojure.tools.build.api/uber now takes ~45 seconds instead of 5 minutes.

πŸŽ‰ 2