(ns perf-test(:use (criterium core))(:gen-class))(def o (Object.))(defn foo [x](if (> x 0)(inc x)(do(monitor-enter o)(let [res (dec x)](monitor-exit 0)res))))(defn bar [x](if (> x 0)(inc x)(dec x)))(defn locking-part [x l](monitor-enter l)(let [res (dec x)](monitor-exit l)res))(defn baz [x](if (> x 0)(inc x)(locking-part x o)))(defn -main [](println "benching foo")(bench (foo 5) :verbose)(println "benching bar")(bench (bar 5) :verbose)(println "benching baz")(bench (baz 5) :verbose)(println "done benching"))
I'm only ever calling these functions with positive values, so the monitor-enter branch should never be entered. Nevertheless, the performance of foo is much worse than bar or baz.The best guess I've got is that the fact that lock-taking is involved somehow changes how the function is compiled, somehow making the function slower. If the practical upshot is that I shouldn't write functions that only sometimes lock -- that the locking part of a function should always be its own function -- then I can do that, but I'm curious why.$ lein uberjar Compiling perf-test Created /Users/mike/perf-test/target/perf-test-0.1.0-SNAPSHOT.jar Created /Users/mike/perf-test/target/perf-test-0.1.0-SNAPSHOT-standalone.jar $ java -jar -server target/perf-test-0.1.0-SNAPSHOT-standalone.jar benching foo WARNING: Final GC required 1.5974571326266802 % of runtime x86_64 Mac OS X 10.8.3 4 cpu(s) Java HotSpot(TM) 64-Bit Server VM 24.0-b28 Runtime arguments: Evaluation count : 391582560 in 60 samples of 6526376 calls. Execution time sample mean : 167.426696 ns Execution time mean : 167.459429 ns Execution time sample std-deviation : 4.079466 ns Execution time std-deviation : 4.097819 ns Execution time lower quantile : 160.742869 ns ( 2.5%) Execution time upper quantile : 175.453376 ns (97.5%) Overhead used : 1.634996 ns Found 2 outliers in 60 samples (3.3333 %) low-severe 2 (3.3333 %) Variance from outliers : 12.5602 % Variance is moderately inflated by outliers benching bar x86_64 Mac OS X 10.8.3 4 cpu(s) Java HotSpot(TM) 64-Bit Server VM 24.0-b28 Runtime arguments: Evaluation count : 2174037300 in 60 samples of 36233955 calls. Execution time sample mean : 26.068923 ns Execution time mean : 26.066422 ns Execution time sample std-deviation : 0.887937 ns Execution time std-deviation : 0.916861 ns Execution time lower quantile : 23.996763 ns ( 2.5%) Execution time upper quantile : 27.911936 ns (97.5%) Overhead used : 1.634996 ns Found 3 outliers in 60 samples (5.0000 %) low-severe 1 (1.6667 %) low-mild 1 (1.6667 %) high-mild 1 (1.6667 %) Variance from outliers : 22.1874 % Variance is moderately inflated by outliers benching baz x86_64 Mac OS X 10.8.3 4 cpu(s) Java HotSpot(TM) 64-Bit Server VM 24.0-b28 Runtime arguments: Evaluation count : 2270676660 in 60 samples of 37844611 calls. Execution time sample mean : 25.834142 ns Execution time mean : 25.837429 ns Execution time sample std-deviation : 0.718382 ns Execution time std-deviation : 0.729431 ns Execution time lower quantile : 24.837925 ns ( 2.5%) Execution time upper quantile : 27.595781 ns (97.5%) Overhead used : 1.634996 ns Found 4 outliers in 60 samples (6.6667 %) low-severe 2 (3.3333 %) low-mild 2 (3.3333 %) Variance from outliers : 15.7591 % Variance is moderately inflated by outliers done benching
You received this message because you are subscribed to a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/x86VygZYf4Y/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojure+u...@googlegroups.com.