Reputation: 5977
I associate a key to a hash map for 10000000 time. 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 code do the same thing, but the clojure version runs exstreamly slow!!
What's the problem?
Upvotes: 6
Views: 650
Reputation: 1264
You can also increase Java code speed with declaring HashMap size in declaration
HashMap<Integer, Integer> mp = new HashMap<Integer, Integer>(10000000);
I guess it is a also a way for REPL (I do not know it), is it possible to reserve memory space?
Upvotes: 0
Reputation: 91534
The first step with performance problems like this is to turn on reflection warnings and remove any.
(set! *warn-on-reflection* true)
Also loop and recur have the lowest overhead.
Upvotes: 9
Reputation: 4619
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
Upvotes: 13