Fork me on GitHub
#off-topic
<
2022-02-05
>
Benjamin09:02:27

I just realized there is a consistency between _ variables and vim black hole register _

👀 1
Martynas Maciulevičius10:02:06

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

Alex Miller (Clojure team)12:02:55

Aren't these all derivatives of Prolog?

2
andy.fingerhut18:02:08

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

😂 7
💯 5
pez21:02:17

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

p-himik21:02:19

That's really interesting, would love to read a follow-up once you figure it out!

😄 1
pez21:02:35

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. 😃

👍 1
pez23:02:27

It starts to toggle on JDK8. With JDK7 I get only the 0.5X runs.

pez10:02:12

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

Gulli10:02:51

Yeah just saw that on HN!

Ben Sless10:02:08

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

😂 1
pez17:02:50

The mystery seems to be solved now. See the updated blog post, if your'e curious. 😃

p-himik17:02:56

Sweet, thanks!

p-himik17:02:54

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."

pez20:02:48

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

pez23:02:11

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.)