我在调整一些性能敏感代码时遇到了这个问题:
user> (use 'criterium.core)
nil
user> (def n (into {} (for [i (range 20000) :let [k (keyword (str i))]] [k {k k}])))
#'user/n
user> (quick-bench (-> n :1 :1))
WARNING: Final GC required 32.5115186521176 % of runtime
Evaluation count : 15509754 in 6 samples of 2584959 calls.
Execution time mean : 36.256135 ns
Execution time std-deviation : 1.076403 ns
Execution time lower quantile : 35.120871 ns ( 2.5%)
Execution time upper quantile : 37.470993 ns (97.5%)
Overhead used : 1.755171 ns
nil
user> (quick-bench (get-in n [:1 :1]))
WARNING: Final GC required 33.11057826481865 % of runtime
Evaluation count : 7681728 in 6 samples of 1280288 calls.
Execution time mean : 81.023429 ns
Execution time std-deviation : 3.244516 ns
Execution time lower quantile : 78.220643 ns ( 2.5%)
Execution time upper quantile : 85.906898 ns (97.5%)
Overhead used : 1.755171 ns
nil
Run Code Online (Sandbox Code Playgroud)
这对我来说不直观,它get-in
比通过get
s 线程的两倍慢,因为它get-in
似乎被定义为对这类事物更好的抽象.
有没有人知道为什么会出现这种情况(技术上和哲学上)?
嵌套映射在Clojure程序中非常常用.这是一件好事.但是有时可以通过展开来改进嵌套地图操作,例如assoc-in
和get-in
.(get :a (get :b (get :c (get :d m)))
与(get-in m [:d :c :b :a])
生成的字节代码不同.后面的字节代码导致更差的执行时间.
请注意,Clojure有一些与此相关的待定补丁http://dev.clojure.org/jira/browse/CLJ-1656.
归档时间: |
|
查看次数: |
160 次 |
最近记录: |