Why is java native HashMap in clojure running slow?

I associate the key with the hash card 10,000,000 times. Here's the Java code and output:

import java.util.HashMap; public class TestMap { public static void main(String[] args) { HashMap<Integer, Integer> mp = new HashMap<Integer, Integer>(); long start = System.currentTimeMillis(); for (int i = 0; i < 10000000; i++) { mp.put(1, 1); } long end = System.currentTimeMillis(); System.out.println("Elapsed time: " + (end - start) + " msecs"); } } $ javac TestMap.java && java -cp . TestMap Elapsed time: 38 msecs 

And then I call java from clojure in REPL:

 user=> (import java.util.HashMap) java.util.HashMap user=> (def mp (HashMap.)) #'user/mp user=> (time (dotimes [n 10000000] (.put mp 1 1))) "Elapsed time: 10024.797 msecs" nil 

Both codes do the same, but the clojure version is slower!

What is the problem?

+6
source share
3 answers

add type hint is better:

 user> (import 'java.util.HashMap) java.util.HashMap user> (def mp (HashMap.)) #'user/mp user> (time (dotimes [n 10000000] (.put mp 1 1))) "Elapsed time: 13932.248126 msecs" nil user> (time (dotimes [n 10000000] (.put ^HashMap mp 1 1))) "Elapsed time: 117.915992 msecs" nil 
+13
source

The first step with such performance issues is to enable reflection alerts and remove any.

  (set! *warn-on-reflection* true) 

In addition, loop and repetition have the lowest overhead.

+9
source

You can also increase the speed of Java code with a HashMap size declaration in the declaration

 HashMap<Integer, Integer> mp = new HashMap<Integer, Integer>(10000000); 

I think this is also a way for REPL (I don't know that), is it possible to reserve memory space?

0
source

Source: https://habr.com/ru/post/919295/


All Articles