Closed christian-esken closed 7 years ago
This is the magic of the Gradle wrapper, you don't need to figure it out yourself. As the JavaDoc for the GetPutBenchmark states,
./gradlew jmh -PincludePattern=GetPutBenchmark
In jmh.gradle it has the plugin settings. It states that you can use benchmarkParameters
as...
Benchmark parameters: Seperated by '&' for parameter types, and ',' for multiple values
I'm usually lazy and edit the Java file locally when exploring, though.
Some of the benchmarks are for checking for any performance issues or experimentation, rather than outside use. Since benchmarks are often wrong, misunderstood, manipulated, etc. I prefer minimalism to not over state (or imply), misreport by over complicating, etc in those that I describe. That's why you'll see just the two as I can explain them fairly, even though there are many other details that might be of interest. Those can be more difficult to explain without fear of misunderstandings, so best left to development and not to confuse users. For users showing if it is fast enough to meet their performance budgets is the primary goal.
I am mainly interested in core benchmarks that can be run for most caches, like GetPutBenchmark. Once knowing the name of the class (GetPutBenchmark) it gets easier. I am not yet familiar with the gradle jmh plugin to spot that benchmarkParameters is applied to \@Param. Thanks for clarifying, this makes it very easy. What do you think of mentioning the gradle 4.0 requirement?
I don't think it needs to be mentioned if you use the wrapper. That installs the version for the project defined in gradle/wrapper/gradle-wrapper.properties
. Since that is the idiomatic way to run Gradle, I think it's better since upgrades are fairly regular. Of course sometimes that breaks plugins and I don't always check jmh when updating, so if I broke that let me know and I'll dig into a fix.
I tried to run it within IntelliJ IDEA via "use default gradle wrapper" and that failed. Only when pointing IntelliJ to a local gradle 4.0.2, I got it working. Its not really worth keeping this issue open for that, though I personally tend to run gradle on server machines directly instead of the wrapper. I will be offline for a couple of days, and if you like you can close this issue. I will try to reproduce the gradle trouble when I get back, and will come back to you if I can reproduce it reliably.
Okay, I use Eclipse but try to keep things working for IntelliJ folks. I run tasks at the command line. Since I don't check jmh or IntelliJ regularly, if it's busted then I can look into a fix. I guess we can close, but not a big deal either way.
Also feel free to fork the benchmarks to bootstrap your own suite, e.g. as cache2k and collisions did.
I did a quick test on the train and saw that I broke the benchmarkParams
at some point. That should be fixed now, sorry. I gave it a non-scientific run so the numbers are rough as I am on a laptop, using battery, with other stuff running.
./gradlew jmh -PincludePattern=GetPutBenchmark \
-PbenchmarkParameters=cacheType=TCache_Lru,TCache_Lfu
Benchmark (cacheType) Mode Cnt Score Error Units
GetPutBenchmark.read_only TCache_Lru thrpt 10 30780838.627 ± 4638449.427 ops/s
GetPutBenchmark.read_only TCache_Lfu thrpt 10 27041235.665 ± 853354.312 ops/s
GetPutBenchmark.readwrite TCache_Lru thrpt 10 23615279.925 ± 3828354.093 ops/s
GetPutBenchmark.readwrite:readwrite_get TCache_Lru thrpt 10 19492469.512 ± 3034092.917 ops/s
GetPutBenchmark.readwrite:readwrite_put TCache_Lru thrpt 10 4122810.413 ± 877353.105 ops/s
GetPutBenchmark.readwrite TCache_Lfu thrpt 10 28617429.557 ± 2738865.133 ops/s
GetPutBenchmark.readwrite:readwrite_get TCache_Lfu thrpt 10 24185446.587 ± 2056324.626 ops/s
GetPutBenchmark.readwrite:readwrite_put TCache_Lfu thrpt 10 4431982.970 ± 727174.167 ops/s
GetPutBenchmark.write_only TCache_Lru thrpt 10 17466518.407 ± 5662496.764 ops/s
GetPutBenchmark.write_only TCache_Lfu thrpt 10 19071051.318 ± 2420626.652 ops/s
Given that your approach is a high watermark with async evaluation, in the past I remember thinking the numbers looked like TCache might be thrashing on a CAS field somewhere. The score looked like that type of contention (lock contention is similar but different numbers). I never dug in to find where, but using a profiler should find it readily. JMH's stacktrace might work, or I have CacheProfiler
as a little testing tool for attaching YourKit to. I'm sure if you fix that it will perform closer to a raw ConcurrentHashMap
as expected.
You ran it with triava v1.0.3, right? There has been 2 performance issues that I fixed in v1.0.4. Still there are issues in the GET that I cannot explain, even using YourKit. I will try to see what your CacheProfiler is about. Performance should be close to ConcurrentHashMap at least for GET's, and I will benchmark that. Also I want to plugin another backing Map, for some fun and insight I thought I might try ConcurrentLinkedHashMap.
v1.0.4, so maybe jmh profilers will help. My ad hoc profiler is just for yourkit, but jmh's are more low level.
CLHM decorates CHM so it might not be too insightful, unfortunately.
FYI: I today tested plenty in YourKit with "CPU, sampling" and "CPU, tracing", but the results were misleading. Then I simply scanned code and you are right. I am thrashing on AtomicLong in the cache statistics. I moved to LongAdder, boosting the readonly benchmark from 30 Mio/s to 80 Mio/s. That is going in the right direction. :-)
Nice! I didn't mean intend to enable statistics and it wasn't obvious when I wrote the code that they were on by default. We should probably disable it in these benchmarks to be fair/comparable to others. Glad the default behavior is better now!
I wanted to run the Caffeine benchmarks, to check the latest changes in the triava cche changes. I have some feedback about the Caffeine documentation. I did not know where you would like to put those, so I did not to a PR (yet). I can do that if I get directions how to proceed.
Two questions: