I've found the time to experiment myself and report my findings below.
In CLJS, MapEntry seems to work fine, and is slightly faster than using a vector to represent it. Below are dumb micro benchmarks, executed in fresh repls void of any other dependencies:
> clj -Sdeps "{:deps {org.clojure/clojurescript {:mvn/version \"1.10.339\"}}}" -m cljs.main
ClojureScript 1.10.339
(simple-benchmark [rng (range 1000)]
(into {} (map (fn [n] [n n]) rng))
1000)
[rng (range 1000)], (into {} (map (fn [n] [n n]) rng)), 1000 runs, 923 msecs
nil
(simple-benchmark [rng (range 1000)]
(into {} (map (fn [n] (MapEntry. n n nil)) rng))
1000)
[rng (range 1000)], (into {} (map (fn [n] (MapEntry. n n nil)) rng)), 1000 runs, 840 msecs
nil
```
In this example, using MapEntry yields a 9% improvements.
In the Clojure side, there are 2 important differences. #1 MapEntry is not part of clojure.core in clojure.lang, so using it requires a JVM-specific import. #2 The MapEntry constructor doesn't need the third "hash" parameter like CLJS, only the key and value. So using MapEntry in cljc code will require reader conditional in `ns` and in each call-site.
```
(import clojure.lang.MapEntry)
(criterium/bench (let [rng (range 1000)]
(into {} (map (fn [n] [n n]) rng))))
Evaluation count : 317760 in 60 samples of 5296 calls.
Execution time mean : 189.335048 µs
Execution time std-deviation : 613.930267 ns
Execution time lower quantile : 188.569507 µs ( 2.5%)
Execution time upper quantile : 191.256133 µs (97.5%)
Overhead used : 1.867366 ns
Found 6 outliers in 60 samples (10.0000 %)
low-severe 3 (5.0000 %)
low-mild 3 (5.0000 %)
Variance from outliers : 1.6389 % Variance is slightly inflated by outliers
=> nil
(criterium/bench (let [rng (range 1000)]
(into {} (map (fn [n] (MapEntry. n n)) rng))))
Evaluation count : 401880 in 60 samples of 6698 calls.
Execution time mean : 149.182354 µs
Execution time std-deviation : 255.340674 ns
Execution time lower quantile : 148.692324 µs ( 2.5%)
Execution time upper quantile : 149.779548 µs (97.5%)
Overhead used : 1.867366 ns
Found 3 outliers in 60 samples (5.0000 %)
low-severe 3 (5.0000 %)
Variance from outliers : 1.6389 % Variance is slightly inflated by outliers
=> nil
```
This other dumb benchmarks shows a 26% speed improvements.
In my case, since I'm coding in cljc file I'm not totally confortable with the reader conditional. Furthermore I don't understand yet all the implications, apart from making the code that produce the map entries less flexible (a sequence of vectors is less generic than a sequence of map entries).
I'd love to hear from you specialists.
PS: I couldn't get clojure cli to download criterium to run the benchmark, so I ended up using the REPL provided by in my current app setup (based on Clojure 1.9.0, Boot 2.8.2 and criterium 0.4.4, the latest stable versions).
Here's the command I ran and the error:
```
> clj -Sdeps "{:deps {org.clojure/clojure {:mvn/version \"1.9.0\"} criterum {:mvn/version \"0.4.4\"}}}"
org.eclipse.aether.resolution.ArtifactResolutionException: Could not find artifact criterum:criterum:jar:0.4.4 in central (
https://repo1.maven.org/maven2/)
at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:422)
at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifacts(DefaultArtifactResolver.java:224)
at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolveArtifact(DefaultArtifactResolver.java:201)
at org.eclipse.aether.internal.impl.DefaultRepositorySystem.resolveArtifact(DefaultRepositorySystem.java:260)
at clojure.tools.deps.alpha.extensions.maven$get_artifact.invokeStatic(maven.clj:95)
at clojure.tools.deps.alpha.extensions.maven$get_artifact.invoke(maven.clj:91)
at clojure.tools.deps.alpha.extensions.maven$eval698$fn__700.invoke(maven.clj:112)
at clojure.lang.MultiFn.invoke(MultiFn.java:243)
at clojure.tools.deps.alpha$lib_paths$fn__1068.invoke(alpha.clj:203)
at clojure.core.protocols$iter_reduce.invokeStatic(protocols.clj:49)
at clojure.core.protocols$fn__7839.invokeStatic(protocols.clj:75)
at clojure.core.protocols$fn__7839.invoke(protocols.clj:75)
at clojure.core.protocols$fn__7781$G__7776__7794.invoke(protocols.clj:13)
at clojure.core$reduce.invokeStatic(core.clj:6748)
at clojure.core$reduce.invoke(core.clj:6730)
at clojure.tools.deps.alpha$lib_paths.invokeStatic(alpha.clj:199)
at clojure.tools.deps.alpha$lib_paths.invoke(alpha.clj:197)
at clojure.tools.deps.alpha$resolve_deps.invokeStatic(alpha.clj:229)
at clojure.tools.deps.alpha$resolve_deps.invoke(alpha.clj:210)
at clojure.tools.deps.alpha.script.make_classpath$create_classpath.invokeStatic(make_classpath.clj:59)
at clojure.tools.deps.alpha.script.make_classpath$create_classpath.invoke(make_classpath.clj:52)
at clojure.tools.deps.alpha.script.make_classpath$run.invokeStatic(make_classpath.clj:70)
at clojure.tools.deps.alpha.script.make_classpath$run.invoke(make_classpath.clj:64)
at clojure.tools.deps.alpha.script.make_classpath$_main.invokeStatic(make_classpath.clj:109)
at clojure.tools.deps.alpha.script.make_classpath$_main.doInvoke(make_classpath.clj:84)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.lang.Var.applyTo(Var.java:702)
at clojure.core$apply.invokeStatic(core.clj:657)
at clojure.main$main_opt.invokeStatic(main.clj:317)
at clojure.main$main_opt.invoke(main.clj:313)
at clojure.main$main.invokeStatic(main.clj:424)
at clojure.main$main.doInvoke(main.clj:387)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.lang.Var.applyTo(Var.java:702)
at clojure.main.main(main.java:37)
Caused by: org.eclipse.aether.transfer.ArtifactNotFoundException: Could not find artifact criterum:criterum:jar:0.4.4 in central (
https://repo1.maven.org/maven2/)
at org.eclipse.aether.connector.basic.ArtifactTransportListener.transferFailed(ArtifactTransportListener.java:48)
at org.eclipse.aether.connector.basic.BasicRepositoryConnector$TaskRunner.run(BasicRepositoryConnector.java:365)
at org.eclipse.aether.util.concurrency.RunnableErrorForwarder$1.run(RunnableErrorForwarder.java:75)
at org.eclipse.aether.connector.basic.BasicRepositoryConnector$DirectExecutor.execute(BasicRepositoryConnector.java:583)
at org.eclipse.aether.connector.basic.BasicRepositoryConnector.get(BasicRepositoryConnector.java:259)
at org.eclipse.aether.internal.impl.DefaultArtifactResolver.performDownloads(DefaultArtifactResolver.java:498)
at org.eclipse.aether.internal.impl.DefaultArtifactResolver.resolve(DefaultArtifactResolver.java:399)
... 34 more
```