This page is not created by, affiliated with, or supported by Slack Technologies, Inc.

## 2022-02-05

## Channels

- # announcements (1)
- # aws (6)
- # babashka (8)
- # beginners (22)
- # cider (12)
- # clj-kondo (1)
- # cljdoc (15)
- # clojure (109)
- # clojure-dev (6)
- # clojure-europe (40)
- # clojure-losangeles (5)
- # clojure-uk (1)
- # clojurescript (28)
- # data-oriented-programming (3)
- # datahike (9)
- # datalevin (9)
- # holy-lambda (2)
- # juxt (5)
- # lsp (4)
- # malli (2)
- # meander (1)
- # missionary (5)
- # nextjournal (3)
- # off-topic (17)
- # reagent (1)
- # reitit (8)
- # releases (1)
- # sci (16)
- # shadow-cljs (7)
- # sql (9)
- # tools-deps (9)
- # transit (1)

I just realized there is a consistency between `_`

variables and vim black hole register `_`

Yes, you're right. It was decided that Vim would reuse the same pattern 😄 Also Scala copied that too.

I decided to get this off my chest. Comments, questions, suggestions for "improvement" all welcome: https://github.com/jafingerhut/approxsemver

Thiis is actually somewhat on-topic, but anyway 😃 https://blog.agical.se/en/posts/java-bitset-performance-mystery

Out of ideas right now, but I'm not able to let this rest so will hopefully be able to post follow-ups, even if ”figured it out” is somewhat of a stretch goal. 😃

Some HN people find it interesting too. https://news.ycombinator.com/item?id=30226083

> Am I reading this right, you bought a €730 machine just to investigate why 20 lines of code occasionally runs slow? YES.jpg

Made me recall how I was reading a newest-at-the-time C++ standard (11, I think) which introduced primitives for operations on multi-CPU machines. "Nope, skipping this."

I get a feeling that a lot of containerized JVM applications out there run at crippled speed.

There is still mystery in this story. I can get my boolean-array sieve written in Clojure to start toggling performance in a similar way, even if the performance difference is smaller. However, pinning the JVM + mem using numactl does **not** make a difference. This code runs at a stable 11K passes/5 secs:

```
(set! *unchecked-math* true)
(defn sieve-ba
"Java boolean array storage
Returns the raw sieve with only odd numbers present."
[^long n]
(if (< n 2)
(boolean-array 0)
(let [sqrt-n (unchecked-long (Math/ceil (Math/sqrt (double n))))
half-n (unchecked-int (bit-shift-right n 1))
primes (boolean-array half-n)]
(loop [p 3]
(when (< p sqrt-n)
(when-not (aget primes (bit-shift-right p 1))
(loop [i (long (bit-shift-right (* p p) 1))]
(when (< i half-n)
(aset primes i true)
(recur (+ i p)))))
(recur (+ p 2))))
primes)))
0 - Passes: 11129
1 - Passes: 10978
2 - Passes: 11140
3 - Passes: 11196
4 - Passes: 10965
5 - Passes: 11043
6 - Passes: 11048
7 - Passes: 11088
8 - Passes: 11047
9 - Passes: 11078
```

Whereas this flickers:
```
(set! *unchecked-math* true)
(defn sieve-ba
"Java boolean array storage
Returns the raw sieve with only odd numbers present."
[^long n]
(if (< n 2)
(boolean-array 0)
(let [sqrt-n (unchecked-int (Math/ceil (Math/sqrt (double n))))
half-n (unchecked-int (bit-shift-right n 1))
primes (boolean-array half-n)]
(loop [p 3]
(when (< p sqrt-n)
(when-not (aget primes (bit-shift-right p 1))
(loop [i (long (bit-shift-right (* p p) 1))]
(when (< i half-n)
(aset primes i true)
(recur (+ i p)))))
(recur (+ p 2))))
primes)))
0 - Passes: 11037
1 - Passes: 10862
2 - Passes: 11096
3 - Passes: 9742
4 - Passes: 9755
5 - Passes: 9805
6 - Passes: 9818
7 - Passes: 9719
8 - Passes: 9849
9 - Passes: 9809
```

Spotting the difference? Yes, `unchecked-int`

for `sqrt-n`

instead of `unchecked-long`

. (And the decompiled Java code shows only this difference as well.)