From 4ee4f923eac0e8acde5409c86fcb8d757070b2d4 Mon Sep 17 00:00:00 2001 From: Abduqodiri Qurbonzoda Date: Fri, 31 May 2019 16:32:14 +0300 Subject: [PATCH] Benchmarking other immutable collections libraries --- .gitignore | 2 + .../.idea/copyright/apache_2_0.xml | 6 + .../.idea/copyright/profiles_settings.xml | 3 + benchmarks-libraries/build.gradle | 61 +++++ .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54413 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + benchmarks-libraries/settings.gradle | 17 ++ .../src/jmh/java/benchmarks/IntWrapper.kt | 38 ++++ .../benchmarks/immutableList/clojure/List.kt | 166 ++++++++++++++ .../clojure/builder/ListBuilder.kt | 146 ++++++++++++ .../benchmarks/immutableList/cyclops/List.kt | 166 ++++++++++++++ .../benchmarks/immutableList/kotlin/List.kt | 166 ++++++++++++++ .../kotlin/builder/ListBuilder.kt | 184 +++++++++++++++ .../benchmarks/immutableList/paguro/List.kt | 166 ++++++++++++++ .../paguro/builder/ListBuilder.kt | 184 +++++++++++++++ .../benchmarks/immutableList/scala/List.kt | 166 ++++++++++++++ .../benchmarks/immutableList/vavr/List.kt | 166 ++++++++++++++ .../benchmarks/immutableMap/capsule/Map.kt | 169 ++++++++++++++ .../capsule/builder/MapBuilder.kt | 196 ++++++++++++++++ .../benchmarks/immutableMap/clojure/Map.kt | 169 ++++++++++++++ .../clojure/builder/MapBuilder.kt | 149 ++++++++++++ .../immutableMap/clojureSorted/Map.kt | 169 ++++++++++++++ .../benchmarks/immutableMap/cyclops/Map.kt | 169 ++++++++++++++ .../immutableMap/cyclopsOrdered/Map.kt | 169 ++++++++++++++ .../immutableMap/cyclopsTrie/Map.kt | 169 ++++++++++++++ .../benchmarks/immutableMap/kotlin/Map.kt | 169 ++++++++++++++ .../immutableMap/kotlin/builder/MapBuilder.kt | 196 ++++++++++++++++ .../immutableMap/kotlinOrdered/Map.kt | 169 ++++++++++++++ .../kotlinOrdered/builder/MapBuilder.kt | 196 ++++++++++++++++ .../benchmarks/immutableMap/paguro/Map.kt | 169 ++++++++++++++ .../immutableMap/paguro/builder/MapBuilder.kt | 196 ++++++++++++++++ .../immutableMap/paguroSorted/Map.kt | 169 ++++++++++++++ .../java/benchmarks/immutableMap/scala/Map.kt | 169 ++++++++++++++ .../immutableMap/scalaSorted/Map.kt | 169 ++++++++++++++ .../java/benchmarks/immutableMap/vavr/Map.kt | 169 ++++++++++++++ .../immutableMap/vavrOrdered/Map.kt | 169 ++++++++++++++ .../benchmarks/immutableMap/vavrSorted/Map.kt | 169 ++++++++++++++ .../benchmarks/immutableSet/capsule/Set.kt | 154 +++++++++++++ .../capsule/builder/SetBuilder.kt | 182 +++++++++++++++ .../benchmarks/immutableSet/clojure/Set.kt | 154 +++++++++++++ .../clojure/builder/SetBuilder.kt | 149 ++++++++++++ .../immutableSet/clojureSorted/Set.kt | 154 +++++++++++++ .../benchmarks/immutableSet/cyclops/Set.kt | 154 +++++++++++++ .../immutableSet/cyclopsSorted/Set.kt | 154 +++++++++++++ .../immutableSet/cyclopsTrie/Set.kt | 154 +++++++++++++ .../benchmarks/immutableSet/kotlin/Set.kt | 154 +++++++++++++ .../immutableSet/kotlin/builder/SetBuilder.kt | 182 +++++++++++++++ .../immutableSet/kotlinOrdered/Set.kt | 154 +++++++++++++ .../kotlinOrdered/builder/SetBuilder.kt | 182 +++++++++++++++ .../java/benchmarks/immutableSet/scala/Set.kt | 154 +++++++++++++ .../immutableSet/scalaSorted/Set.kt | 154 +++++++++++++ .../java/benchmarks/immutableSet/vavr/Set.kt | 154 +++++++++++++ .../immutableSet/vavrOrdered/Set.kt | 154 +++++++++++++ .../benchmarks/immutableSet/vavrSorted/Set.kt | 154 +++++++++++++ .../src/jmh/java/benchmarks/utils.kt | 52 +++++ .../kotlin/generators/CommonUtilsGenerator.kt | 62 +++++ .../kotlin/generators/IntWrapperGenerator.kt | 48 ++++ .../generators/benchmarkSourceGenerator.kt | 210 +++++++++++++++++ .../generators/immutableList/impl/clojure.kt | 48 ++++ .../generators/immutableList/impl/cyclops.kt | 48 ++++ .../generators/immutableList/impl/kotlin.kt | 48 ++++ .../immutableList/impl/listImplementation.kt | 36 +++ .../generators/immutableList/impl/paguro.kt | 48 ++++ .../generators/immutableList/impl/scala.kt | 48 ++++ .../generators/immutableList/impl/vavr.kt | 48 ++++ .../immutableList/listBenchmarksGenerator.kt | 170 ++++++++++++++ .../immutableListBuilder/impl/clojure.kt | 47 ++++ .../immutableListBuilder/impl/kotlin.kt | 47 ++++ .../impl/listBuilderImplementation.kt | 41 ++++ .../immutableListBuilder/impl/paguro.kt | 47 ++++ .../listBuilderBenchmarksGenerator.kt | 202 +++++++++++++++++ .../generators/immutableMap/impl/capsule.kt | 39 ++++ .../generators/immutableMap/impl/clojure.kt | 39 ++++ .../immutableMap/impl/clojureSorted.kt | 39 ++++ .../generators/immutableMap/impl/cyclops.kt | 39 ++++ .../immutableMap/impl/cyclopsOrdered.kt | 39 ++++ .../immutableMap/impl/cyclopsTrie.kt | 39 ++++ .../generators/immutableMap/impl/kotlin.kt | 39 ++++ .../immutableMap/impl/kotlinOrdered.kt | 39 ++++ .../immutableMap/impl/mapImplementation.kt | 34 +++ .../generators/immutableMap/impl/paguro.kt | 39 ++++ .../immutableMap/impl/paguroSorted.kt | 39 ++++ .../generators/immutableMap/impl/scala.kt | 39 ++++ .../immutableMap/impl/scalaSorted.kt | 39 ++++ .../generators/immutableMap/impl/vavr.kt | 39 ++++ .../immutableMap/impl/vavrOrdered.kt | 39 ++++ .../immutableMap/impl/vavrSorted.kt | 39 ++++ .../immutableMap/mapBenchmarksGenerator.kt | 180 +++++++++++++++ .../immutableMapBuilder/impl/capsule.kt | 45 ++++ .../immutableMapBuilder/impl/clojure.kt | 45 ++++ .../immutableMapBuilder/impl/kotlin.kt | 45 ++++ .../immutableMapBuilder/impl/kotlinOrdered.kt | 45 ++++ .../impl/mapBuilderImplementation.kt | 38 ++++ .../immutableMapBuilder/impl/paguro.kt | 45 ++++ .../mapBuilderBenchmarksGenerator.kt | 213 ++++++++++++++++++ .../generators/immutableSet/impl/capsule.kt | 32 +++ .../generators/immutableSet/impl/clojure.kt | 32 +++ .../immutableSet/impl/clojureSorted.kt | 32 +++ .../generators/immutableSet/impl/cyclops.kt | 32 +++ .../immutableSet/impl/cyclopsSorted.kt | 32 +++ .../immutableSet/impl/cyclopsTrie.kt | 32 +++ .../generators/immutableSet/impl/kotlin.kt | 32 +++ .../immutableSet/impl/kotlinOrdered.kt | 32 +++ .../generators/immutableSet/impl/scala.kt | 32 +++ .../immutableSet/impl/scalaSorted.kt | 32 +++ .../immutableSet/impl/setImplementation.kt | 29 +++ .../generators/immutableSet/impl/vavr.kt | 32 +++ .../immutableSet/impl/vavrOrdered.kt | 32 +++ .../immutableSet/impl/vavrSorted.kt | 32 +++ .../immutableSet/setBenchmarksGenerator.kt | 165 ++++++++++++++ .../immutableSetBuilder/impl/capsule.kt | 43 ++++ .../immutableSetBuilder/impl/clojure.kt | 43 ++++ .../immutableSetBuilder/impl/kotlin.kt | 43 ++++ .../immutableSetBuilder/impl/kotlinOrdered.kt | 43 ++++ .../impl/setBuilderImplementation.kt | 36 +++ .../setBuilderBenchmarksGenerator.kt | 199 ++++++++++++++++ 116 files changed, 11350 insertions(+) create mode 100644 benchmarks-libraries/.idea/copyright/apache_2_0.xml create mode 100644 benchmarks-libraries/.idea/copyright/profiles_settings.xml create mode 100644 benchmarks-libraries/build.gradle create mode 100644 benchmarks-libraries/gradle/wrapper/gradle-wrapper.jar create mode 100644 benchmarks-libraries/gradle/wrapper/gradle-wrapper.properties create mode 100644 benchmarks-libraries/settings.gradle create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/IntWrapper.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableList/clojure/List.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableList/clojure/builder/ListBuilder.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableList/cyclops/List.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableList/kotlin/List.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableList/kotlin/builder/ListBuilder.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableList/paguro/List.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableList/paguro/builder/ListBuilder.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableList/scala/List.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableList/vavr/List.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/capsule/Map.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/capsule/builder/MapBuilder.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/clojure/Map.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/clojure/builder/MapBuilder.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/clojureSorted/Map.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/cyclops/Map.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/cyclopsOrdered/Map.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/cyclopsTrie/Map.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/kotlin/Map.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/kotlin/builder/MapBuilder.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/kotlinOrdered/Map.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/kotlinOrdered/builder/MapBuilder.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/paguro/Map.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/paguro/builder/MapBuilder.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/paguroSorted/Map.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/scala/Map.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/scalaSorted/Map.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/vavr/Map.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/vavrOrdered/Map.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/vavrSorted/Map.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/capsule/Set.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/capsule/builder/SetBuilder.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/clojure/Set.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/clojure/builder/SetBuilder.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/clojureSorted/Set.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/cyclops/Set.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/cyclopsSorted/Set.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/cyclopsTrie/Set.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/kotlin/Set.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/kotlin/builder/SetBuilder.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/kotlinOrdered/Set.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/kotlinOrdered/builder/SetBuilder.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/scala/Set.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/scalaSorted/Set.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/vavr/Set.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/vavrOrdered/Set.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/vavrSorted/Set.kt create mode 100644 benchmarks-libraries/src/jmh/java/benchmarks/utils.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/CommonUtilsGenerator.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/IntWrapperGenerator.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/benchmarkSourceGenerator.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/clojure.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/cyclops.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/kotlin.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/listImplementation.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/paguro.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/scala.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/vavr.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableList/listBenchmarksGenerator.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableListBuilder/impl/clojure.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableListBuilder/impl/kotlin.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableListBuilder/impl/listBuilderImplementation.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableListBuilder/impl/paguro.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableListBuilder/listBuilderBenchmarksGenerator.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/capsule.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/clojure.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/clojureSorted.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/cyclops.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/cyclopsOrdered.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/cyclopsTrie.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/kotlin.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/kotlinOrdered.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/mapImplementation.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/paguro.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/paguroSorted.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/scala.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/scalaSorted.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/vavr.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/vavrOrdered.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/vavrSorted.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableMap/mapBenchmarksGenerator.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/impl/capsule.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/impl/clojure.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/impl/kotlin.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/impl/kotlinOrdered.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/impl/mapBuilderImplementation.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/impl/paguro.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/mapBuilderBenchmarksGenerator.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/capsule.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/clojure.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/clojureSorted.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/cyclops.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/cyclopsSorted.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/cyclopsTrie.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/kotlin.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/kotlinOrdered.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/scala.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/scalaSorted.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/setImplementation.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/vavr.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/vavrOrdered.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/vavrSorted.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableSet/setBenchmarksGenerator.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableSetBuilder/impl/capsule.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableSetBuilder/impl/clojure.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableSetBuilder/impl/kotlin.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableSetBuilder/impl/kotlinOrdered.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableSetBuilder/impl/setBuilderImplementation.kt create mode 100644 benchmarks-libraries/src/main/kotlin/generators/immutableSetBuilder/setBuilderBenchmarksGenerator.kt diff --git a/.gitignore b/.gitignore index 15a025ce..e53a45ab 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ /.idea/* !/.idea/copyright +/benchmarks-libraries/.idea/* +!/benchmarks-libraries/.idea/copyright .gradle *.iml target diff --git a/benchmarks-libraries/.idea/copyright/apache_2_0.xml b/benchmarks-libraries/.idea/copyright/apache_2_0.xml new file mode 100644 index 00000000..bb5022fc --- /dev/null +++ b/benchmarks-libraries/.idea/copyright/apache_2_0.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/benchmarks-libraries/.idea/copyright/profiles_settings.xml b/benchmarks-libraries/.idea/copyright/profiles_settings.xml new file mode 100644 index 00000000..915114f1 --- /dev/null +++ b/benchmarks-libraries/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/benchmarks-libraries/build.gradle b/benchmarks-libraries/build.gradle new file mode 100644 index 00000000..4c2572f0 --- /dev/null +++ b/benchmarks-libraries/build.gradle @@ -0,0 +1,61 @@ +plugins { + id 'org.jetbrains.kotlin.jvm' version '1.3.40' + id "me.champeau.gradle.jmh" version "0.4.8" +} + +repositories { + mavenLocal() + mavenCentral() + jcenter() + maven { url 'http://nexus.usethesource.io/content/repositories/public/' } +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8" + + implementation 'org.jetbrains.kotlinx:kotlinx-collections-immutable:0.2-SNAPSHOT' + implementation 'io.usethesource:capsule:0.6.1' + implementation 'org.organicdesign:Paguro:3.1.2' + implementation 'com.oath.cyclops:cyclops:10.3.0' + implementation 'org.clojure:clojure:1.10.0' + implementation 'org.scala-lang:scala-library:2.13.0' + implementation 'io.vavr:vavr:0.9.3' +} + +compileKotlin { + kotlinOptions.jvmTarget = "1.8" +} + +compileJmhKotlin { + kotlinOptions.jvmTarget = "1.8" +} + +task generateBenchmarkSources(type: JavaExec) { + main = 'generators.BenchmarkSourceGeneratorKt' + classpath = sourceSets.main.runtimeClasspath +} + +jmh { +// include = ['immutableList.*.Add', 'immutableMap', 'immutableSet'] +// exclude = ['builder'] + + profilers = ['gc'] + + resultFormat = "csv" + + fork = 1 + warmupIterations = 7 + iterations = 10 + warmup = '500ms' + timeOnIteration = '500ms' + + benchmarkMode = ['avgt'] + timeUnit = "us" + + benchmarkParameters = [ + 'size':['1', '10', '100', '1000', '10000'], +// 'implementation': ['hash'], + 'hashCodeType':['random', 'collision'], + 'immutablePercentage':['0.0', '80.0'] + ] +} \ No newline at end of file diff --git a/benchmarks-libraries/gradle/wrapper/gradle-wrapper.jar b/benchmarks-libraries/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..91ca28c8b802289c3a438766657a5e98f20eff03 GIT binary patch literal 54413 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 { + override fun hashCode(): Int { + return hashCode + } + + override fun equals(other: Any?): Boolean { + if (other !is IntWrapper) { + return false + } + assert(obj != other.obj || hashCode == other.hashCode) // if elements are equal hashCodes must be equal + return obj == other.obj + } + + override fun compareTo(other: IntWrapper): Int { + return obj.compareTo(other.obj) + } +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableList/clojure/List.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableList/clojure/List.kt new file mode 100644 index 00000000..9d622223 --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableList/clojure/List.kt @@ -0,0 +1,166 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableList.clojure + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Benchmark + fun addLast(): clojure.lang.PersistentVector { + return persistentListAdd(size) + } + + @Benchmark + fun addLastAndIterate(bh: Blackhole) { + val list = persistentListAdd(size) + for (e in list) { + bh.consume(e) + } + } + + @Benchmark + fun addLastAndGet(bh: Blackhole) { + val list = persistentListAdd(size) + for (i in 0 until size) { + bh.consume(list.get(i)) + } + } +} + + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = clojure.lang.PersistentVector.EMPTY + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + } + + @Benchmark + fun getByIndex(bh: Blackhole) { + for (i in 0 until size) { + bh.consume(persistentList.get(i)) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = clojure.lang.PersistentVector.EMPTY + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + } + + @Benchmark + fun firstToLast(bh: Blackhole) { + for (e in persistentList) { + bh.consume(e) + } + } + + @Benchmark + fun lastToFirst(bh: Blackhole) { + val iterator = persistentList.listIterator(size) + + while (iterator.hasPrevious()) { + bh.consume(iterator.previous()) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = clojure.lang.PersistentVector.EMPTY + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + } + + @Benchmark + fun removeLast(): clojure.lang.PersistentVector { + var list = persistentList + repeat(times = size) { + list = list.pop() + } + return list + } +} + + +@State(Scope.Thread) +open class Set { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = clojure.lang.PersistentVector.EMPTY + private var randomIndices = listOf() + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + randomIndices = List(size) { it }.shuffled() + } + + @Benchmark + fun setByIndex(): clojure.lang.PersistentVector { + repeat(times = size) { index -> + persistentList = persistentList.assocN(index, "another element") + } + return persistentList + } + + @Benchmark + fun setByRandomIndex(): clojure.lang.PersistentVector { + repeat(times = size) { index -> + persistentList = persistentList.assocN(randomIndices[index], "another element") + } + return persistentList + } +} + + +private fun persistentListAdd(size: Int): clojure.lang.PersistentVector { + var list = clojure.lang.PersistentVector.EMPTY + repeat(times = size) { + list = list.cons("some element") + } + return list +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableList/clojure/builder/ListBuilder.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableList/clojure/builder/ListBuilder.kt new file mode 100644 index 00000000..d833b2f6 --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableList/clojure/builder/ListBuilder.kt @@ -0,0 +1,146 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableList.clojure.builder + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + @Benchmark + fun addLast(): clojure.lang.ITransientVector { + return persistentListBuilderAdd(size, immutablePercentage) + } + + @Benchmark + fun addLastAndGet(bh: Blackhole) { + val builder = persistentListBuilderAdd(size, immutablePercentage) + for (i in 0 until size) { + bh.consume(builder.valAt(i)) + } + } + + +} + + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var builder: clojure.lang.ITransientVector = clojure.lang.PersistentVector.EMPTY.asTransient() as clojure.lang.ITransientVector + + @Setup(Level.Trial) + fun prepare() { + builder = persistentListBuilderAdd(size, immutablePercentage) + } + + @Benchmark + fun getByIndex(bh: Blackhole) { + for (i in 0 until size) { + bh.consume(builder.valAt(i)) + } + } +} + + + + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + @Benchmark + fun addAndRemoveLast(): clojure.lang.ITransientVector { + val builder = persistentListBuilderAdd(size, immutablePercentage) + for (i in 0 until size) { + builder.pop() + } + return builder + } +} + + +@State(Scope.Thread) +open class Set { + @Param("10000", "100000") + var size: Int = 0 + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var builder = clojure.lang.PersistentVector.EMPTY.asTransient() as clojure.lang.ITransientVector + private var randomIndices = listOf() + + @Setup(Level.Trial) + fun prepare() { + builder = persistentListBuilderAdd(size, immutablePercentage) + randomIndices = List(size) { it }.shuffled() + } + + @Benchmark + fun setByIndex(): clojure.lang.ITransientVector { + for (i in 0 until size) { + builder.assocN(i, "another element") + } + return builder + } + + @Benchmark + fun setByRandomIndex(): clojure.lang.ITransientVector { + for (i in 0 until size) { + builder.assocN(randomIndices[i], "another element") + } + return builder + } +} + + +private fun persistentListBuilderAdd(size: Int, immutablePercentage: Double): clojure.lang.ITransientVector { + val immutableSize = immutableSize(size, immutablePercentage) + + var list = clojure.lang.PersistentVector.EMPTY + repeat(times = immutableSize) { + list = list.cons("another element") + } + + val builder = list.asTransient() as clojure.lang.ITransientVector + repeat(times = size - immutableSize) { + builder.conj("some element") + } + + return builder +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableList/cyclops/List.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableList/cyclops/List.kt new file mode 100644 index 00000000..f1beecfb --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableList/cyclops/List.kt @@ -0,0 +1,166 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableList.cyclops + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Benchmark + fun addLast(): cyclops.data.Vector { + return persistentListAdd(size) + } + + @Benchmark + fun addLastAndIterate(bh: Blackhole) { + val list = persistentListAdd(size) + for (e in list) { + bh.consume(e) + } + } + + @Benchmark + fun addLastAndGet(bh: Blackhole) { + val list = persistentListAdd(size) + for (i in 0 until size) { + bh.consume(list.get(i)) + } + } +} + + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = cyclops.data.Vector.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + } + + @Benchmark + fun getByIndex(bh: Blackhole) { + for (i in 0 until size) { + bh.consume(persistentList.get(i)) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = cyclops.data.Vector.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + } + + @Benchmark + fun firstToLast(bh: Blackhole) { + for (e in persistentList) { + bh.consume(e) + } + } + + @Benchmark + fun lastToFirst(bh: Blackhole) { + val iterator = persistentList.reverse().iterator() + + while (iterator.hasNext()) { + bh.consume(iterator.next()) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = cyclops.data.Vector.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + } + + @Benchmark + fun removeLast(): cyclops.data.Vector { + var list = persistentList + repeat(times = size) { + list = list.dropRight(1) + } + return list + } +} + + +@State(Scope.Thread) +open class Set { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = cyclops.data.Vector.empty() + private var randomIndices = listOf() + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + randomIndices = List(size) { it }.shuffled() + } + + @Benchmark + fun setByIndex(): cyclops.data.Vector { + repeat(times = size) { index -> + persistentList = persistentList.updateAt(index, "another element") + } + return persistentList + } + + @Benchmark + fun setByRandomIndex(): cyclops.data.Vector { + repeat(times = size) { index -> + persistentList = persistentList.updateAt(randomIndices[index], "another element") + } + return persistentList + } +} + + +private fun persistentListAdd(size: Int): cyclops.data.Vector { + var list = cyclops.data.Vector.empty() + repeat(times = size) { + list = list.plus("some element") + } + return list +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableList/kotlin/List.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableList/kotlin/List.kt new file mode 100644 index 00000000..39a24526 --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableList/kotlin/List.kt @@ -0,0 +1,166 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableList.kotlin + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Benchmark + fun addLast(): kotlinx.collections.immutable.PersistentList { + return persistentListAdd(size) + } + + @Benchmark + fun addLastAndIterate(bh: Blackhole) { + val list = persistentListAdd(size) + for (e in list) { + bh.consume(e) + } + } + + @Benchmark + fun addLastAndGet(bh: Blackhole) { + val list = persistentListAdd(size) + for (i in 0 until size) { + bh.consume(list.get(i)) + } + } +} + + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = kotlinx.collections.immutable.persistentListOf() + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + } + + @Benchmark + fun getByIndex(bh: Blackhole) { + for (i in 0 until size) { + bh.consume(persistentList.get(i)) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = kotlinx.collections.immutable.persistentListOf() + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + } + + @Benchmark + fun firstToLast(bh: Blackhole) { + for (e in persistentList) { + bh.consume(e) + } + } + + @Benchmark + fun lastToFirst(bh: Blackhole) { + val iterator = persistentList.listIterator(size) + + while (iterator.hasPrevious()) { + bh.consume(iterator.previous()) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = kotlinx.collections.immutable.persistentListOf() + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + } + + @Benchmark + fun removeLast(): kotlinx.collections.immutable.PersistentList { + var list = persistentList + repeat(times = size) { + list = list.removeAt(list.size - 1) + } + return list + } +} + + +@State(Scope.Thread) +open class Set { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = kotlinx.collections.immutable.persistentListOf() + private var randomIndices = listOf() + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + randomIndices = List(size) { it }.shuffled() + } + + @Benchmark + fun setByIndex(): kotlinx.collections.immutable.PersistentList { + repeat(times = size) { index -> + persistentList = persistentList.set(index, "another element") + } + return persistentList + } + + @Benchmark + fun setByRandomIndex(): kotlinx.collections.immutable.PersistentList { + repeat(times = size) { index -> + persistentList = persistentList.set(randomIndices[index], "another element") + } + return persistentList + } +} + + +private fun persistentListAdd(size: Int): kotlinx.collections.immutable.PersistentList { + var list = kotlinx.collections.immutable.persistentListOf() + repeat(times = size) { + list = list.add("some element") + } + return list +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableList/kotlin/builder/ListBuilder.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableList/kotlin/builder/ListBuilder.kt new file mode 100644 index 00000000..67b4d60b --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableList/kotlin/builder/ListBuilder.kt @@ -0,0 +1,184 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableList.kotlin.builder + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + @Benchmark + fun addLast(): kotlinx.collections.immutable.PersistentList.Builder { + return persistentListBuilderAdd(size, immutablePercentage) + } + + @Benchmark + fun addLastAndGet(bh: Blackhole) { + val builder = persistentListBuilderAdd(size, immutablePercentage) + for (i in 0 until size) { + bh.consume(builder.get(i)) + } + } + + + @Benchmark + fun addLastAndIterate(bh: Blackhole) { + val builder = persistentListBuilderAdd(size, immutablePercentage) + for (e in builder) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var builder: kotlinx.collections.immutable.PersistentList.Builder = kotlinx.collections.immutable.persistentListOf().builder() + + @Setup(Level.Trial) + fun prepare() { + builder = persistentListBuilderAdd(size, immutablePercentage) + } + + @Benchmark + fun getByIndex(bh: Blackhole) { + for (i in 0 until size) { + bh.consume(builder.get(i)) + } + } +} + + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var builder = kotlinx.collections.immutable.persistentListOf().builder() + + @Setup(Level.Trial) + fun prepare() { + builder = persistentListBuilderAdd(size, immutablePercentage) + } + + @Benchmark + fun firstToLast(bh: Blackhole) { + for (e in builder) { + bh.consume(e) + } + } + + @Benchmark + fun lastToFirst(bh: Blackhole) { + val iterator = builder.listIterator(size) + + while (iterator.hasPrevious()) { + bh.consume(iterator.previous()) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + @Benchmark + fun addAndRemoveLast(): kotlinx.collections.immutable.PersistentList.Builder { + val builder = persistentListBuilderAdd(size, immutablePercentage) + for (i in 0 until size) { + builder.removeAt(builder.size - 1) + } + return builder + } +} + + +@State(Scope.Thread) +open class Set { + @Param("10000", "100000") + var size: Int = 0 + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var builder = kotlinx.collections.immutable.persistentListOf().builder() + private var randomIndices = listOf() + + @Setup(Level.Trial) + fun prepare() { + builder = persistentListBuilderAdd(size, immutablePercentage) + randomIndices = List(size) { it }.shuffled() + } + + @Benchmark + fun setByIndex(): kotlinx.collections.immutable.PersistentList.Builder { + for (i in 0 until size) { + builder.set(i, "another element") + } + return builder + } + + @Benchmark + fun setByRandomIndex(): kotlinx.collections.immutable.PersistentList.Builder { + for (i in 0 until size) { + builder.set(randomIndices[i], "another element") + } + return builder + } +} + + +private fun persistentListBuilderAdd(size: Int, immutablePercentage: Double): kotlinx.collections.immutable.PersistentList.Builder { + val immutableSize = immutableSize(size, immutablePercentage) + + var list = kotlinx.collections.immutable.persistentListOf() + repeat(times = immutableSize) { + list = list.add("another element") + } + + val builder = list.builder() + repeat(times = size - immutableSize) { + builder.add("some element") + } + + return builder +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableList/paguro/List.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableList/paguro/List.kt new file mode 100644 index 00000000..91964acb --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableList/paguro/List.kt @@ -0,0 +1,166 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableList.paguro + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Benchmark + fun addLast(): org.organicdesign.fp.collections.RrbTree.ImRrbt { + return persistentListAdd(size) + } + + @Benchmark + fun addLastAndIterate(bh: Blackhole) { + val list = persistentListAdd(size) + for (e in list) { + bh.consume(e) + } + } + + @Benchmark + fun addLastAndGet(bh: Blackhole) { + val list = persistentListAdd(size) + for (i in 0 until size) { + bh.consume(list.get(i)) + } + } +} + + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = org.organicdesign.fp.collections.RrbTree.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + } + + @Benchmark + fun getByIndex(bh: Blackhole) { + for (i in 0 until size) { + bh.consume(persistentList.get(i)) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = org.organicdesign.fp.collections.RrbTree.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + } + + @Benchmark + fun firstToLast(bh: Blackhole) { + for (e in persistentList) { + bh.consume(e) + } + } + + @Benchmark + fun lastToFirst(bh: Blackhole) { + val iterator = persistentList.listIterator(size) + + while (iterator.hasPrevious()) { + bh.consume(iterator.previous()) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = org.organicdesign.fp.collections.RrbTree.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + } + + @Benchmark + fun removeLast(): org.organicdesign.fp.collections.RrbTree.ImRrbt { + var list = persistentList + repeat(times = size) { + list = list.without(list.size - 1) + } + return list + } +} + + +@State(Scope.Thread) +open class Set { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = org.organicdesign.fp.collections.RrbTree.empty() + private var randomIndices = listOf() + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + randomIndices = List(size) { it }.shuffled() + } + + @Benchmark + fun setByIndex(): org.organicdesign.fp.collections.RrbTree.ImRrbt { + repeat(times = size) { index -> + persistentList = persistentList.replace(index, "another element") + } + return persistentList + } + + @Benchmark + fun setByRandomIndex(): org.organicdesign.fp.collections.RrbTree.ImRrbt { + repeat(times = size) { index -> + persistentList = persistentList.replace(randomIndices[index], "another element") + } + return persistentList + } +} + + +private fun persistentListAdd(size: Int): org.organicdesign.fp.collections.RrbTree.ImRrbt { + var list = org.organicdesign.fp.collections.RrbTree.empty() + repeat(times = size) { + list = list.append("some element") + } + return list +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableList/paguro/builder/ListBuilder.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableList/paguro/builder/ListBuilder.kt new file mode 100644 index 00000000..8d303afd --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableList/paguro/builder/ListBuilder.kt @@ -0,0 +1,184 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableList.paguro.builder + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + @Benchmark + fun addLast(): org.organicdesign.fp.collections.RrbTree.MutableRrbt { + return persistentListBuilderAdd(size, immutablePercentage) + } + + @Benchmark + fun addLastAndGet(bh: Blackhole) { + val builder = persistentListBuilderAdd(size, immutablePercentage) + for (i in 0 until size) { + bh.consume(builder.get(i)) + } + } + + + @Benchmark + fun addLastAndIterate(bh: Blackhole) { + val builder = persistentListBuilderAdd(size, immutablePercentage) + for (e in builder) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var builder: org.organicdesign.fp.collections.RrbTree.MutableRrbt = org.organicdesign.fp.collections.RrbTree.emptyMutable() + + @Setup(Level.Trial) + fun prepare() { + builder = persistentListBuilderAdd(size, immutablePercentage) + } + + @Benchmark + fun getByIndex(bh: Blackhole) { + for (i in 0 until size) { + bh.consume(builder.get(i)) + } + } +} + + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var builder = org.organicdesign.fp.collections.RrbTree.emptyMutable() + + @Setup(Level.Trial) + fun prepare() { + builder = persistentListBuilderAdd(size, immutablePercentage) + } + + @Benchmark + fun firstToLast(bh: Blackhole) { + for (e in builder) { + bh.consume(e) + } + } + + @Benchmark + fun lastToFirst(bh: Blackhole) { + val iterator = builder.listIterator(size) + + while (iterator.hasPrevious()) { + bh.consume(iterator.previous()) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + @Benchmark + fun addAndRemoveLast(): org.organicdesign.fp.collections.RrbTree.MutableRrbt { + val builder = persistentListBuilderAdd(size, immutablePercentage) + for (i in 0 until size) { + builder.without(builder.size - 1) + } + return builder + } +} + + +@State(Scope.Thread) +open class Set { + @Param("10000", "100000") + var size: Int = 0 + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var builder = org.organicdesign.fp.collections.RrbTree.emptyMutable() + private var randomIndices = listOf() + + @Setup(Level.Trial) + fun prepare() { + builder = persistentListBuilderAdd(size, immutablePercentage) + randomIndices = List(size) { it }.shuffled() + } + + @Benchmark + fun setByIndex(): org.organicdesign.fp.collections.RrbTree.MutableRrbt { + for (i in 0 until size) { + builder.replace(i, "another element") + } + return builder + } + + @Benchmark + fun setByRandomIndex(): org.organicdesign.fp.collections.RrbTree.MutableRrbt { + for (i in 0 until size) { + builder.replace(randomIndices[i], "another element") + } + return builder + } +} + + +private fun persistentListBuilderAdd(size: Int, immutablePercentage: Double): org.organicdesign.fp.collections.RrbTree.MutableRrbt { + val immutableSize = immutableSize(size, immutablePercentage) + + var list = org.organicdesign.fp.collections.RrbTree.empty() + repeat(times = immutableSize) { + list = list.append("another element") + } + + val builder = list.mutable() + repeat(times = size - immutableSize) { + builder.append("some element") + } + + return builder +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableList/scala/List.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableList/scala/List.kt new file mode 100644 index 00000000..a475e7bc --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableList/scala/List.kt @@ -0,0 +1,166 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableList.scala + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Benchmark + fun addLast(): scala.collection.immutable.Vector { + return persistentListAdd(size) + } + + @Benchmark + fun addLastAndIterate(bh: Blackhole) { + val list = persistentListAdd(size) + for (e in list) { + bh.consume(e) + } + } + + @Benchmark + fun addLastAndGet(bh: Blackhole) { + val list = persistentListAdd(size) + for (i in 0 until size) { + bh.consume(list.apply(i)) + } + } +} + + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = scala.collection.immutable.`Vector$`.`MODULE$`.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + } + + @Benchmark + fun getByIndex(bh: Blackhole) { + for (i in 0 until size) { + bh.consume(persistentList.apply(i)) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = scala.collection.immutable.`Vector$`.`MODULE$`.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + } + + @Benchmark + fun firstToLast(bh: Blackhole) { + for (e in persistentList) { + bh.consume(e) + } + } + + @Benchmark + fun lastToFirst(bh: Blackhole) { + val iterator = persistentList.reverseIterator() + + while (iterator.hasNext()) { + bh.consume(iterator.next()) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = scala.collection.immutable.`Vector$`.`MODULE$`.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + } + + @Benchmark + fun removeLast(): scala.collection.immutable.Vector { + var list = persistentList + repeat(times = size) { + list = list.dropRight(1) + } + return list + } +} + + +@State(Scope.Thread) +open class Set { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = scala.collection.immutable.`Vector$`.`MODULE$`.empty() + private var randomIndices = listOf() + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + randomIndices = List(size) { it }.shuffled() + } + + @Benchmark + fun setByIndex(): scala.collection.immutable.Vector { + repeat(times = size) { index -> + persistentList = persistentList.updateAt(index, "another element") + } + return persistentList + } + + @Benchmark + fun setByRandomIndex(): scala.collection.immutable.Vector { + repeat(times = size) { index -> + persistentList = persistentList.updateAt(randomIndices[index], "another element") + } + return persistentList + } +} + + +private fun persistentListAdd(size: Int): scala.collection.immutable.Vector { + var list = scala.collection.immutable.`Vector$`.`MODULE$`.empty() + repeat(times = size) { + list = list.appended("some element") as scala.collection.immutable.Vector + } + return list +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableList/vavr/List.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableList/vavr/List.kt new file mode 100644 index 00000000..414364b0 --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableList/vavr/List.kt @@ -0,0 +1,166 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableList.vavr + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Benchmark + fun addLast(): io.vavr.collection.Vector { + return persistentListAdd(size) + } + + @Benchmark + fun addLastAndIterate(bh: Blackhole) { + val list = persistentListAdd(size) + for (e in list) { + bh.consume(e) + } + } + + @Benchmark + fun addLastAndGet(bh: Blackhole) { + val list = persistentListAdd(size) + for (i in 0 until size) { + bh.consume(list.apply(i)) + } + } +} + + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = io.vavr.collection.Vector.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + } + + @Benchmark + fun getByIndex(bh: Blackhole) { + for (i in 0 until size) { + bh.consume(persistentList.apply(i)) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = io.vavr.collection.Vector.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + } + + @Benchmark + fun firstToLast(bh: Blackhole) { + for (e in persistentList) { + bh.consume(e) + } + } + + @Benchmark + fun lastToFirst(bh: Blackhole) { + val iterator = persistentList.reverseIterator() + + while (iterator.hasNext()) { + bh.consume(iterator.next()) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = io.vavr.collection.Vector.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + } + + @Benchmark + fun removeLast(): io.vavr.collection.Vector { + var list = persistentList + repeat(times = size) { + list = list.dropRight(1) + } + return list + } +} + + +@State(Scope.Thread) +open class Set { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = io.vavr.collection.Vector.empty() + private var randomIndices = listOf() + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + randomIndices = List(size) { it }.shuffled() + } + + @Benchmark + fun setByIndex(): io.vavr.collection.Vector { + repeat(times = size) { index -> + persistentList = persistentList.update(index, "another element") + } + return persistentList + } + + @Benchmark + fun setByRandomIndex(): io.vavr.collection.Vector { + repeat(times = size) { index -> + persistentList = persistentList.update(randomIndices[index], "another element") + } + return persistentList + } +} + + +private fun persistentListAdd(size: Int): io.vavr.collection.Vector { + var list = io.vavr.collection.Vector.empty() + repeat(times = size) { + list = list.append("some element") + } + return list +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/capsule/Map.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/capsule/Map.kt new file mode 100644 index 00000000..bb70955a --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/capsule/Map.kt @@ -0,0 +1,169 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableMap.capsule + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = io.usethesource.capsule.core.PersistentTrieMap.of() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + + } + + @Benchmark + fun get(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentMap.get(keys[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentMap = io.usethesource.capsule.core.PersistentTrieMap.of() + + @Setup(Level.Trial) + fun prepare() { + persistentMap = persistentMapPut(generateKeys(hashCodeType, size)) + } + + @Benchmark + fun iterateKeys(bh: Blackhole) { + for (k in persistentMap.keys) { + bh.consume(k) + } + } + + @Benchmark + fun iterateValues(bh: Blackhole) { + for (v in persistentMap.values) { + bh.consume(v) + } + } + + @Benchmark + fun iterateEntries(bh: Blackhole) { + for (e in persistentMap) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Put { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun put(): io.usethesource.capsule.Map.Immutable { + return persistentMapPut(keys) + } + + @Benchmark + fun putAndGet(bh: Blackhole) { + val map = persistentMapPut(keys) + repeat(times = size) { index -> + bh.consume(map.get(keys[index])) + } + } + + @Benchmark + fun putAndIterateKeys(bh: Blackhole) { + val map = persistentMapPut(keys) + for (key in map.keys) { + bh.consume(key) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = io.usethesource.capsule.core.PersistentTrieMap.of() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun remove(): io.usethesource.capsule.Map.Immutable { + var map = persistentMap + repeat(times = size) { index -> + map = map.__remove(keys[index]) + } + return map + } +} + + +private fun persistentMapPut(keys: List): io.usethesource.capsule.Map.Immutable { + var map = io.usethesource.capsule.core.PersistentTrieMap.of() + for (key in keys) { + map = map.__put(key, "some element") + } + return map +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/capsule/builder/MapBuilder.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/capsule/builder/MapBuilder.kt new file mode 100644 index 00000000..e4ba081c --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/capsule/builder/MapBuilder.kt @@ -0,0 +1,196 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableMap.capsule.builder + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var keys = listOf() + private var builder = io.usethesource.capsule.core.PersistentTrieMap.of().asTransient() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + builder = persistentMapBuilderPut(keys, immutablePercentage) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun get(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(builder.get(keys[index])) + } + } +} + + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var builder = io.usethesource.capsule.core.PersistentTrieMap.of().asTransient() + + @Setup(Level.Trial) + fun prepare() { + val keys = generateKeys(hashCodeType, size) + builder = persistentMapBuilderPut(keys, immutablePercentage) + } + + @Benchmark + fun iterateKeys(bh: Blackhole) { + for (k in builder.keys) { + bh.consume(k) + } + } + + @Benchmark + fun iterateValues(bh: Blackhole) { + for (v in builder.values) { + bh.consume(v) + } + } + + @Benchmark + fun iterateEntries(bh: Blackhole) { + for (e in builder) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Put { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var keys = listOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun put(): io.usethesource.capsule.Map.Transient { + return persistentMapBuilderPut(keys, immutablePercentage) + } + + @Benchmark + fun putAndGet(bh: Blackhole) { + val builder = persistentMapBuilderPut(keys, immutablePercentage) + repeat(times = size) { index -> + bh.consume(builder.get(keys[index])) + } + } + + + @Benchmark + fun putAndIterateKeys(bh: Blackhole) { + val builder = persistentMapBuilderPut(keys, immutablePercentage) + for (key in builder.keys) { + bh.consume(key) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var keys = listOf() + private var keysToRemove = listOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + + keysToRemove = if (hashCodeType == NON_EXISTING_HASH_CODE) { + generateKeys(hashCodeType, size) + } else { + keys + } + } + + @Benchmark + fun putAndRemove(): io.usethesource.capsule.Map.Transient { + val builder = persistentMapBuilderPut(keys, immutablePercentage) + repeat(times = size) { index -> + builder.remove(keysToRemove[index]) + } + return builder + } +} + + +private fun persistentMapBuilderPut( + keys: List, + immutablePercentage: Double +): io.usethesource.capsule.Map.Transient { + val immutableSize = immutableSize(keys.size, immutablePercentage) + + var map = io.usethesource.capsule.core.PersistentTrieMap.of() + for (index in 0 until immutableSize) { + map = map.__put(keys[index], "some element") + } + + val builder = map.asTransient() + for (index in immutableSize until keys.size) { + builder.put(keys[index], "some element") + } + + return builder +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/clojure/Map.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/clojure/Map.kt new file mode 100644 index 00000000..21adb693 --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/clojure/Map.kt @@ -0,0 +1,169 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableMap.clojure + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = clojure.lang.PersistentHashMap.EMPTY + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + + } + + @Benchmark + fun get(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentMap.valAt(keys[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentMap = clojure.lang.PersistentHashMap.EMPTY + + @Setup(Level.Trial) + fun prepare() { + persistentMap = persistentMapPut(generateKeys(hashCodeType, size)) + } + + @Benchmark + fun iterateKeys(bh: Blackhole) { + for (k in persistentMap.keys) { + bh.consume(k) + } + } + + @Benchmark + fun iterateValues(bh: Blackhole) { + for (v in persistentMap.values) { + bh.consume(v) + } + } + + @Benchmark + fun iterateEntries(bh: Blackhole) { + for (e in persistentMap) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Put { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun put(): clojure.lang.PersistentHashMap { + return persistentMapPut(keys) + } + + @Benchmark + fun putAndGet(bh: Blackhole) { + val map = persistentMapPut(keys) + repeat(times = size) { index -> + bh.consume(map.valAt(keys[index])) + } + } + + @Benchmark + fun putAndIterateKeys(bh: Blackhole) { + val map = persistentMapPut(keys) + for (key in map.keys) { + bh.consume(key) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = clojure.lang.PersistentHashMap.EMPTY + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun remove(): clojure.lang.PersistentHashMap { + var map = persistentMap + repeat(times = size) { index -> + map = map.without(keys[index]) as clojure.lang.PersistentHashMap + } + return map + } +} + + +private fun persistentMapPut(keys: List): clojure.lang.PersistentHashMap { + var map = clojure.lang.PersistentHashMap.EMPTY + for (key in keys) { + map = map.assoc(key, "some element") as clojure.lang.PersistentHashMap + } + return map +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/clojure/builder/MapBuilder.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/clojure/builder/MapBuilder.kt new file mode 100644 index 00000000..61c80c21 --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/clojure/builder/MapBuilder.kt @@ -0,0 +1,149 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableMap.clojure.builder + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var keys = listOf() + private var builder = clojure.lang.PersistentHashMap.EMPTY.asTransient() as clojure.lang.ATransientMap + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + builder = persistentMapBuilderPut(keys, immutablePercentage) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun get(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(builder.valAt(keys[index])) + } + } +} + + + + + +@State(Scope.Thread) +open class Put { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var keys = listOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun put(): clojure.lang.ATransientMap { + return persistentMapBuilderPut(keys, immutablePercentage) + } + + @Benchmark + fun putAndGet(bh: Blackhole) { + val builder = persistentMapBuilderPut(keys, immutablePercentage) + repeat(times = size) { index -> + bh.consume(builder.valAt(keys[index])) + } + } + + +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var keys = listOf() + private var keysToRemove = listOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + + keysToRemove = if (hashCodeType == NON_EXISTING_HASH_CODE) { + generateKeys(hashCodeType, size) + } else { + keys + } + } + + @Benchmark + fun putAndRemove(): clojure.lang.ATransientMap { + val builder = persistentMapBuilderPut(keys, immutablePercentage) + repeat(times = size) { index -> + builder.without(keysToRemove[index]) + } + return builder + } +} + + +private fun persistentMapBuilderPut( + keys: List, + immutablePercentage: Double +): clojure.lang.ATransientMap { + val immutableSize = immutableSize(keys.size, immutablePercentage) + + var map = clojure.lang.PersistentHashMap.EMPTY as clojure.lang.IPersistentMap + for (index in 0 until immutableSize) { + map = map.assoc(keys[index], "some element") + } + + val builder = (map as clojure.lang.PersistentHashMap).asTransient() as clojure.lang.ATransientMap + for (index in immutableSize until keys.size) { + builder.assoc(keys[index], "some element") + } + + return builder +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/clojureSorted/Map.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/clojureSorted/Map.kt new file mode 100644 index 00000000..6a515b43 --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/clojureSorted/Map.kt @@ -0,0 +1,169 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableMap.clojureSorted + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = clojure.lang.PersistentTreeMap.EMPTY + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + + } + + @Benchmark + fun get(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentMap.valAt(keys[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentMap = clojure.lang.PersistentTreeMap.EMPTY + + @Setup(Level.Trial) + fun prepare() { + persistentMap = persistentMapPut(generateKeys(hashCodeType, size)) + } + + @Benchmark + fun iterateKeys(bh: Blackhole) { + for (k in persistentMap.keys) { + bh.consume(k) + } + } + + @Benchmark + fun iterateValues(bh: Blackhole) { + for (v in persistentMap.values) { + bh.consume(v) + } + } + + @Benchmark + fun iterateEntries(bh: Blackhole) { + for (e in persistentMap) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Put { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun put(): clojure.lang.PersistentTreeMap { + return persistentMapPut(keys) + } + + @Benchmark + fun putAndGet(bh: Blackhole) { + val map = persistentMapPut(keys) + repeat(times = size) { index -> + bh.consume(map.valAt(keys[index])) + } + } + + @Benchmark + fun putAndIterateKeys(bh: Blackhole) { + val map = persistentMapPut(keys) + for (key in map.keys) { + bh.consume(key) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = clojure.lang.PersistentTreeMap.EMPTY + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun remove(): clojure.lang.PersistentTreeMap { + var map = persistentMap + repeat(times = size) { index -> + map = map.without(keys[index]) + } + return map + } +} + + +private fun persistentMapPut(keys: List): clojure.lang.PersistentTreeMap { + var map = clojure.lang.PersistentTreeMap.EMPTY + for (key in keys) { + map = map.assoc(key, "some element") + } + return map +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/cyclops/Map.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/cyclops/Map.kt new file mode 100644 index 00000000..b4c9b08a --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/cyclops/Map.kt @@ -0,0 +1,169 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableMap.cyclops + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = cyclops.data.HashMap.empty() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + + } + + @Benchmark + fun get(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentMap.get(keys[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentMap = cyclops.data.HashMap.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentMap = persistentMapPut(generateKeys(hashCodeType, size)) + } + + @Benchmark + fun iterateKeys(bh: Blackhole) { + for (k in persistentMap.keys()) { + bh.consume(k) + } + } + + @Benchmark + fun iterateValues(bh: Blackhole) { + for (v in persistentMap.values()) { + bh.consume(v) + } + } + + @Benchmark + fun iterateEntries(bh: Blackhole) { + for (e in persistentMap) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Put { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun put(): cyclops.data.HashMap { + return persistentMapPut(keys) + } + + @Benchmark + fun putAndGet(bh: Blackhole) { + val map = persistentMapPut(keys) + repeat(times = size) { index -> + bh.consume(map.get(keys[index])) + } + } + + @Benchmark + fun putAndIterateKeys(bh: Blackhole) { + val map = persistentMapPut(keys) + for (key in map.keys()) { + bh.consume(key) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = cyclops.data.HashMap.empty() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun remove(): cyclops.data.HashMap { + var map = persistentMap + repeat(times = size) { index -> + map = map.remove(keys[index]) + } + return map + } +} + + +private fun persistentMapPut(keys: List): cyclops.data.HashMap { + var map = cyclops.data.HashMap.empty() + for (key in keys) { + map = map.put(key, "some element") + } + return map +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/cyclopsOrdered/Map.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/cyclopsOrdered/Map.kt new file mode 100644 index 00000000..5a8bbd79 --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/cyclopsOrdered/Map.kt @@ -0,0 +1,169 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableMap.cyclopsOrdered + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = cyclops.data.LinkedMap.empty() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + + } + + @Benchmark + fun get(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentMap.get(keys[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentMap = cyclops.data.LinkedMap.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentMap = persistentMapPut(generateKeys(hashCodeType, size)) + } + + @Benchmark + fun iterateKeys(bh: Blackhole) { + for (k in persistentMap.keys()) { + bh.consume(k) + } + } + + @Benchmark + fun iterateValues(bh: Blackhole) { + for (v in persistentMap.values()) { + bh.consume(v) + } + } + + @Benchmark + fun iterateEntries(bh: Blackhole) { + for (e in persistentMap) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Put { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun put(): cyclops.data.LinkedMap { + return persistentMapPut(keys) + } + + @Benchmark + fun putAndGet(bh: Blackhole) { + val map = persistentMapPut(keys) + repeat(times = size) { index -> + bh.consume(map.get(keys[index])) + } + } + + @Benchmark + fun putAndIterateKeys(bh: Blackhole) { + val map = persistentMapPut(keys) + for (key in map.keys()) { + bh.consume(key) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = cyclops.data.LinkedMap.empty() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun remove(): cyclops.data.LinkedMap { + var map = persistentMap + repeat(times = size) { index -> + map = map.remove(keys[index]) + } + return map + } +} + + +private fun persistentMapPut(keys: List): cyclops.data.LinkedMap { + var map = cyclops.data.LinkedMap.empty() + for (key in keys) { + map = map.put(key, "some element") + } + return map +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/cyclopsTrie/Map.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/cyclopsTrie/Map.kt new file mode 100644 index 00000000..9c665391 --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/cyclopsTrie/Map.kt @@ -0,0 +1,169 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableMap.cyclopsTrie + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = cyclops.data.TrieMap.empty() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + + } + + @Benchmark + fun get(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentMap.get(keys[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentMap = cyclops.data.TrieMap.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentMap = persistentMapPut(generateKeys(hashCodeType, size)) + } + + @Benchmark + fun iterateKeys(bh: Blackhole) { + for (k in persistentMap.keys()) { + bh.consume(k) + } + } + + @Benchmark + fun iterateValues(bh: Blackhole) { + for (v in persistentMap.values()) { + bh.consume(v) + } + } + + @Benchmark + fun iterateEntries(bh: Blackhole) { + for (e in persistentMap) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Put { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun put(): cyclops.data.TrieMap { + return persistentMapPut(keys) + } + + @Benchmark + fun putAndGet(bh: Blackhole) { + val map = persistentMapPut(keys) + repeat(times = size) { index -> + bh.consume(map.get(keys[index])) + } + } + + @Benchmark + fun putAndIterateKeys(bh: Blackhole) { + val map = persistentMapPut(keys) + for (key in map.keys()) { + bh.consume(key) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = cyclops.data.TrieMap.empty() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun remove(): cyclops.data.TrieMap { + var map = persistentMap + repeat(times = size) { index -> + map = map.remove(keys[index]) + } + return map + } +} + + +private fun persistentMapPut(keys: List): cyclops.data.TrieMap { + var map = cyclops.data.TrieMap.empty() + for (key in keys) { + map = map.put(key, "some element") + } + return map +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/kotlin/Map.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/kotlin/Map.kt new file mode 100644 index 00000000..a73a2e12 --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/kotlin/Map.kt @@ -0,0 +1,169 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableMap.kotlin + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = kotlinx.collections.immutable.persistentHashMapOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + + } + + @Benchmark + fun get(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentMap.get(keys[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentMap = kotlinx.collections.immutable.persistentHashMapOf() + + @Setup(Level.Trial) + fun prepare() { + persistentMap = persistentMapPut(generateKeys(hashCodeType, size)) + } + + @Benchmark + fun iterateKeys(bh: Blackhole) { + for (k in persistentMap.keys) { + bh.consume(k) + } + } + + @Benchmark + fun iterateValues(bh: Blackhole) { + for (v in persistentMap.values) { + bh.consume(v) + } + } + + @Benchmark + fun iterateEntries(bh: Blackhole) { + for (e in persistentMap) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Put { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun put(): kotlinx.collections.immutable.PersistentMap { + return persistentMapPut(keys) + } + + @Benchmark + fun putAndGet(bh: Blackhole) { + val map = persistentMapPut(keys) + repeat(times = size) { index -> + bh.consume(map.get(keys[index])) + } + } + + @Benchmark + fun putAndIterateKeys(bh: Blackhole) { + val map = persistentMapPut(keys) + for (key in map.keys) { + bh.consume(key) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = kotlinx.collections.immutable.persistentHashMapOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun remove(): kotlinx.collections.immutable.PersistentMap { + var map = persistentMap + repeat(times = size) { index -> + map = map.remove(keys[index]) + } + return map + } +} + + +private fun persistentMapPut(keys: List): kotlinx.collections.immutable.PersistentMap { + var map = kotlinx.collections.immutable.persistentHashMapOf() + for (key in keys) { + map = map.put(key, "some element") + } + return map +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/kotlin/builder/MapBuilder.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/kotlin/builder/MapBuilder.kt new file mode 100644 index 00000000..3ebea2fc --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/kotlin/builder/MapBuilder.kt @@ -0,0 +1,196 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableMap.kotlin.builder + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var keys = listOf() + private var builder = kotlinx.collections.immutable.persistentHashMapOf().builder() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + builder = persistentMapBuilderPut(keys, immutablePercentage) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun get(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(builder.get(keys[index])) + } + } +} + + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var builder = kotlinx.collections.immutable.persistentHashMapOf().builder() + + @Setup(Level.Trial) + fun prepare() { + val keys = generateKeys(hashCodeType, size) + builder = persistentMapBuilderPut(keys, immutablePercentage) + } + + @Benchmark + fun iterateKeys(bh: Blackhole) { + for (k in builder.keys) { + bh.consume(k) + } + } + + @Benchmark + fun iterateValues(bh: Blackhole) { + for (v in builder.values) { + bh.consume(v) + } + } + + @Benchmark + fun iterateEntries(bh: Blackhole) { + for (e in builder) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Put { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var keys = listOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun put(): kotlinx.collections.immutable.PersistentMap.Builder { + return persistentMapBuilderPut(keys, immutablePercentage) + } + + @Benchmark + fun putAndGet(bh: Blackhole) { + val builder = persistentMapBuilderPut(keys, immutablePercentage) + repeat(times = size) { index -> + bh.consume(builder.get(keys[index])) + } + } + + + @Benchmark + fun putAndIterateKeys(bh: Blackhole) { + val builder = persistentMapBuilderPut(keys, immutablePercentage) + for (key in builder.keys) { + bh.consume(key) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var keys = listOf() + private var keysToRemove = listOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + + keysToRemove = if (hashCodeType == NON_EXISTING_HASH_CODE) { + generateKeys(hashCodeType, size) + } else { + keys + } + } + + @Benchmark + fun putAndRemove(): kotlinx.collections.immutable.PersistentMap.Builder { + val builder = persistentMapBuilderPut(keys, immutablePercentage) + repeat(times = size) { index -> + builder.remove(keysToRemove[index]) + } + return builder + } +} + + +private fun persistentMapBuilderPut( + keys: List, + immutablePercentage: Double +): kotlinx.collections.immutable.PersistentMap.Builder { + val immutableSize = immutableSize(keys.size, immutablePercentage) + + var map = kotlinx.collections.immutable.persistentHashMapOf() + for (index in 0 until immutableSize) { + map = map.put(keys[index], "some element") + } + + val builder = map.builder() + for (index in immutableSize until keys.size) { + builder.put(keys[index], "some element") + } + + return builder +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/kotlinOrdered/Map.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/kotlinOrdered/Map.kt new file mode 100644 index 00000000..006ede4f --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/kotlinOrdered/Map.kt @@ -0,0 +1,169 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableMap.kotlinOrdered + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = kotlinx.collections.immutable.persistentMapOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + + } + + @Benchmark + fun get(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentMap.get(keys[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentMap = kotlinx.collections.immutable.persistentMapOf() + + @Setup(Level.Trial) + fun prepare() { + persistentMap = persistentMapPut(generateKeys(hashCodeType, size)) + } + + @Benchmark + fun iterateKeys(bh: Blackhole) { + for (k in persistentMap.keys) { + bh.consume(k) + } + } + + @Benchmark + fun iterateValues(bh: Blackhole) { + for (v in persistentMap.values) { + bh.consume(v) + } + } + + @Benchmark + fun iterateEntries(bh: Blackhole) { + for (e in persistentMap) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Put { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun put(): kotlinx.collections.immutable.PersistentMap { + return persistentMapPut(keys) + } + + @Benchmark + fun putAndGet(bh: Blackhole) { + val map = persistentMapPut(keys) + repeat(times = size) { index -> + bh.consume(map.get(keys[index])) + } + } + + @Benchmark + fun putAndIterateKeys(bh: Blackhole) { + val map = persistentMapPut(keys) + for (key in map.keys) { + bh.consume(key) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = kotlinx.collections.immutable.persistentMapOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun remove(): kotlinx.collections.immutable.PersistentMap { + var map = persistentMap + repeat(times = size) { index -> + map = map.remove(keys[index]) + } + return map + } +} + + +private fun persistentMapPut(keys: List): kotlinx.collections.immutable.PersistentMap { + var map = kotlinx.collections.immutable.persistentMapOf() + for (key in keys) { + map = map.put(key, "some element") + } + return map +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/kotlinOrdered/builder/MapBuilder.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/kotlinOrdered/builder/MapBuilder.kt new file mode 100644 index 00000000..3f210703 --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/kotlinOrdered/builder/MapBuilder.kt @@ -0,0 +1,196 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableMap.kotlinOrdered.builder + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var keys = listOf() + private var builder = kotlinx.collections.immutable.persistentMapOf().builder() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + builder = persistentMapBuilderPut(keys, immutablePercentage) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun get(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(builder.get(keys[index])) + } + } +} + + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var builder = kotlinx.collections.immutable.persistentMapOf().builder() + + @Setup(Level.Trial) + fun prepare() { + val keys = generateKeys(hashCodeType, size) + builder = persistentMapBuilderPut(keys, immutablePercentage) + } + + @Benchmark + fun iterateKeys(bh: Blackhole) { + for (k in builder.keys) { + bh.consume(k) + } + } + + @Benchmark + fun iterateValues(bh: Blackhole) { + for (v in builder.values) { + bh.consume(v) + } + } + + @Benchmark + fun iterateEntries(bh: Blackhole) { + for (e in builder) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Put { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var keys = listOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun put(): kotlinx.collections.immutable.PersistentMap.Builder { + return persistentMapBuilderPut(keys, immutablePercentage) + } + + @Benchmark + fun putAndGet(bh: Blackhole) { + val builder = persistentMapBuilderPut(keys, immutablePercentage) + repeat(times = size) { index -> + bh.consume(builder.get(keys[index])) + } + } + + + @Benchmark + fun putAndIterateKeys(bh: Blackhole) { + val builder = persistentMapBuilderPut(keys, immutablePercentage) + for (key in builder.keys) { + bh.consume(key) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var keys = listOf() + private var keysToRemove = listOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + + keysToRemove = if (hashCodeType == NON_EXISTING_HASH_CODE) { + generateKeys(hashCodeType, size) + } else { + keys + } + } + + @Benchmark + fun putAndRemove(): kotlinx.collections.immutable.PersistentMap.Builder { + val builder = persistentMapBuilderPut(keys, immutablePercentage) + repeat(times = size) { index -> + builder.remove(keysToRemove[index]) + } + return builder + } +} + + +private fun persistentMapBuilderPut( + keys: List, + immutablePercentage: Double +): kotlinx.collections.immutable.PersistentMap.Builder { + val immutableSize = immutableSize(keys.size, immutablePercentage) + + var map = kotlinx.collections.immutable.persistentMapOf() + for (index in 0 until immutableSize) { + map = map.put(keys[index], "some element") + } + + val builder = map.builder() + for (index in immutableSize until keys.size) { + builder.put(keys[index], "some element") + } + + return builder +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/paguro/Map.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/paguro/Map.kt new file mode 100644 index 00000000..400da089 --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/paguro/Map.kt @@ -0,0 +1,169 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableMap.paguro + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = org.organicdesign.fp.collections.PersistentHashMap.empty() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + + } + + @Benchmark + fun get(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentMap.get(keys[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentMap = org.organicdesign.fp.collections.PersistentHashMap.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentMap = persistentMapPut(generateKeys(hashCodeType, size)) + } + + @Benchmark + fun iterateKeys(bh: Blackhole) { + for (k in persistentMap.keys) { + bh.consume(k) + } + } + + @Benchmark + fun iterateValues(bh: Blackhole) { + for (v in persistentMap.values) { + bh.consume(v) + } + } + + @Benchmark + fun iterateEntries(bh: Blackhole) { + for (e in persistentMap) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Put { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun put(): org.organicdesign.fp.collections.PersistentHashMap { + return persistentMapPut(keys) + } + + @Benchmark + fun putAndGet(bh: Blackhole) { + val map = persistentMapPut(keys) + repeat(times = size) { index -> + bh.consume(map.get(keys[index])) + } + } + + @Benchmark + fun putAndIterateKeys(bh: Blackhole) { + val map = persistentMapPut(keys) + for (key in map.keys) { + bh.consume(key) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = org.organicdesign.fp.collections.PersistentHashMap.empty() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun remove(): org.organicdesign.fp.collections.PersistentHashMap { + var map = persistentMap + repeat(times = size) { index -> + map = map.without(keys[index]) + } + return map + } +} + + +private fun persistentMapPut(keys: List): org.organicdesign.fp.collections.PersistentHashMap { + var map = org.organicdesign.fp.collections.PersistentHashMap.empty() + for (key in keys) { + map = map.assoc(key, "some element") + } + return map +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/paguro/builder/MapBuilder.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/paguro/builder/MapBuilder.kt new file mode 100644 index 00000000..5034aacb --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/paguro/builder/MapBuilder.kt @@ -0,0 +1,196 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableMap.paguro.builder + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var keys = listOf() + private var builder = org.organicdesign.fp.collections.PersistentHashMap.emptyMutable() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + builder = persistentMapBuilderPut(keys, immutablePercentage) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun get(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(builder.get(keys[index])) + } + } +} + + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var builder = org.organicdesign.fp.collections.PersistentHashMap.emptyMutable() + + @Setup(Level.Trial) + fun prepare() { + val keys = generateKeys(hashCodeType, size) + builder = persistentMapBuilderPut(keys, immutablePercentage) + } + + @Benchmark + fun iterateKeys(bh: Blackhole) { + for (k in builder.keys) { + bh.consume(k) + } + } + + @Benchmark + fun iterateValues(bh: Blackhole) { + for (v in builder.values) { + bh.consume(v) + } + } + + @Benchmark + fun iterateEntries(bh: Blackhole) { + for (e in builder) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Put { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var keys = listOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun put(): org.organicdesign.fp.collections.PersistentHashMap.MutableHashMap { + return persistentMapBuilderPut(keys, immutablePercentage) + } + + @Benchmark + fun putAndGet(bh: Blackhole) { + val builder = persistentMapBuilderPut(keys, immutablePercentage) + repeat(times = size) { index -> + bh.consume(builder.get(keys[index])) + } + } + + + @Benchmark + fun putAndIterateKeys(bh: Blackhole) { + val builder = persistentMapBuilderPut(keys, immutablePercentage) + for (key in builder.keys) { + bh.consume(key) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var keys = listOf() + private var keysToRemove = listOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + + keysToRemove = if (hashCodeType == NON_EXISTING_HASH_CODE) { + generateKeys(hashCodeType, size) + } else { + keys + } + } + + @Benchmark + fun putAndRemove(): org.organicdesign.fp.collections.PersistentHashMap.MutableHashMap { + val builder = persistentMapBuilderPut(keys, immutablePercentage) + repeat(times = size) { index -> + builder.without(keysToRemove[index]) + } + return builder + } +} + + +private fun persistentMapBuilderPut( + keys: List, + immutablePercentage: Double +): org.organicdesign.fp.collections.PersistentHashMap.MutableHashMap { + val immutableSize = immutableSize(keys.size, immutablePercentage) + + var map = org.organicdesign.fp.collections.PersistentHashMap.empty() + for (index in 0 until immutableSize) { + map = map.assoc(keys[index], "some element") + } + + val builder = map.mutable() + for (index in immutableSize until keys.size) { + builder.assoc(keys[index], "some element") + } + + return builder +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/paguroSorted/Map.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/paguroSorted/Map.kt new file mode 100644 index 00000000..610935ea --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/paguroSorted/Map.kt @@ -0,0 +1,169 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableMap.paguroSorted + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = org.organicdesign.fp.collections.PersistentTreeMap.empty() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + + } + + @Benchmark + fun get(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentMap.get(keys[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentMap = org.organicdesign.fp.collections.PersistentTreeMap.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentMap = persistentMapPut(generateKeys(hashCodeType, size)) + } + + @Benchmark + fun iterateKeys(bh: Blackhole) { + for (k in persistentMap.keys) { + bh.consume(k) + } + } + + @Benchmark + fun iterateValues(bh: Blackhole) { + for (v in persistentMap.values) { + bh.consume(v) + } + } + + @Benchmark + fun iterateEntries(bh: Blackhole) { + for (e in persistentMap) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Put { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun put(): org.organicdesign.fp.collections.PersistentTreeMap { + return persistentMapPut(keys) + } + + @Benchmark + fun putAndGet(bh: Blackhole) { + val map = persistentMapPut(keys) + repeat(times = size) { index -> + bh.consume(map.get(keys[index])) + } + } + + @Benchmark + fun putAndIterateKeys(bh: Blackhole) { + val map = persistentMapPut(keys) + for (key in map.keys) { + bh.consume(key) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = org.organicdesign.fp.collections.PersistentTreeMap.empty() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun remove(): org.organicdesign.fp.collections.PersistentTreeMap { + var map = persistentMap + repeat(times = size) { index -> + map = map.without(keys[index]) + } + return map + } +} + + +private fun persistentMapPut(keys: List): org.organicdesign.fp.collections.PersistentTreeMap { + var map = org.organicdesign.fp.collections.PersistentTreeMap.empty() + for (key in keys) { + map = map.assoc(key, "some element") + } + return map +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/scala/Map.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/scala/Map.kt new file mode 100644 index 00000000..cde2153e --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/scala/Map.kt @@ -0,0 +1,169 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableMap.scala + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = scala.collection.immutable.`HashMap$`.`MODULE$`.empty() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + + } + + @Benchmark + fun get(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentMap.get(keys[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentMap = scala.collection.immutable.`HashMap$`.`MODULE$`.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentMap = persistentMapPut(generateKeys(hashCodeType, size)) + } + + @Benchmark + fun iterateKeys(bh: Blackhole) { + for (k in persistentMap.keys()) { + bh.consume(k) + } + } + + @Benchmark + fun iterateValues(bh: Blackhole) { + for (v in persistentMap.values()) { + bh.consume(v) + } + } + + @Benchmark + fun iterateEntries(bh: Blackhole) { + for (e in persistentMap) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Put { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun put(): scala.collection.immutable.HashMap { + return persistentMapPut(keys) + } + + @Benchmark + fun putAndGet(bh: Blackhole) { + val map = persistentMapPut(keys) + repeat(times = size) { index -> + bh.consume(map.get(keys[index])) + } + } + + @Benchmark + fun putAndIterateKeys(bh: Blackhole) { + val map = persistentMapPut(keys) + for (key in map.keys()) { + bh.consume(key) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = scala.collection.immutable.`HashMap$`.`MODULE$`.empty() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun remove(): scala.collection.immutable.HashMap { + var map = persistentMap + repeat(times = size) { index -> + map = map.removed(keys[index]) + } + return map + } +} + + +private fun persistentMapPut(keys: List): scala.collection.immutable.HashMap { + var map = scala.collection.immutable.`HashMap$`.`MODULE$`.empty() + for (key in keys) { + map = map.updated(key, "some element") + } + return map +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/scalaSorted/Map.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/scalaSorted/Map.kt new file mode 100644 index 00000000..be18c193 --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/scalaSorted/Map.kt @@ -0,0 +1,169 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableMap.scalaSorted + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = scala.collection.immutable.`TreeMap$`.`MODULE$`.empty(scala.math.Ordering.comparatorToOrdering(Comparator.naturalOrder())) + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + + } + + @Benchmark + fun get(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentMap.get(keys[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentMap = scala.collection.immutable.`TreeMap$`.`MODULE$`.empty(scala.math.Ordering.comparatorToOrdering(Comparator.naturalOrder())) + + @Setup(Level.Trial) + fun prepare() { + persistentMap = persistentMapPut(generateKeys(hashCodeType, size)) + } + + @Benchmark + fun iterateKeys(bh: Blackhole) { + for (k in persistentMap.keys()) { + bh.consume(k) + } + } + + @Benchmark + fun iterateValues(bh: Blackhole) { + for (v in persistentMap.values()) { + bh.consume(v) + } + } + + @Benchmark + fun iterateEntries(bh: Blackhole) { + for (e in persistentMap) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Put { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun put(): scala.collection.immutable.TreeMap { + return persistentMapPut(keys) + } + + @Benchmark + fun putAndGet(bh: Blackhole) { + val map = persistentMapPut(keys) + repeat(times = size) { index -> + bh.consume(map.get(keys[index])) + } + } + + @Benchmark + fun putAndIterateKeys(bh: Blackhole) { + val map = persistentMapPut(keys) + for (key in map.keys()) { + bh.consume(key) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = scala.collection.immutable.`TreeMap$`.`MODULE$`.empty(scala.math.Ordering.comparatorToOrdering(Comparator.naturalOrder())) + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun remove(): scala.collection.immutable.TreeMap { + var map = persistentMap + repeat(times = size) { index -> + map = map.removed(keys[index]) + } + return map + } +} + + +private fun persistentMapPut(keys: List): scala.collection.immutable.TreeMap { + var map = scala.collection.immutable.`TreeMap$`.`MODULE$`.empty(scala.math.Ordering.comparatorToOrdering(Comparator.naturalOrder())) + for (key in keys) { + map = map.updated(key, "some element") + } + return map +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/vavr/Map.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/vavr/Map.kt new file mode 100644 index 00000000..3ae150b4 --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/vavr/Map.kt @@ -0,0 +1,169 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableMap.vavr + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = io.vavr.collection.HashMap.empty() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + + } + + @Benchmark + fun get(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentMap.get(keys[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentMap = io.vavr.collection.HashMap.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentMap = persistentMapPut(generateKeys(hashCodeType, size)) + } + + @Benchmark + fun iterateKeys(bh: Blackhole) { + for (k in persistentMap.keysIterator()) { + bh.consume(k) + } + } + + @Benchmark + fun iterateValues(bh: Blackhole) { + for (v in persistentMap.valuesIterator()) { + bh.consume(v) + } + } + + @Benchmark + fun iterateEntries(bh: Blackhole) { + for (e in persistentMap) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Put { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun put(): io.vavr.collection.HashMap { + return persistentMapPut(keys) + } + + @Benchmark + fun putAndGet(bh: Blackhole) { + val map = persistentMapPut(keys) + repeat(times = size) { index -> + bh.consume(map.get(keys[index])) + } + } + + @Benchmark + fun putAndIterateKeys(bh: Blackhole) { + val map = persistentMapPut(keys) + for (key in map.keysIterator()) { + bh.consume(key) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = io.vavr.collection.HashMap.empty() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun remove(): io.vavr.collection.HashMap { + var map = persistentMap + repeat(times = size) { index -> + map = map.remove(keys[index]) + } + return map + } +} + + +private fun persistentMapPut(keys: List): io.vavr.collection.HashMap { + var map = io.vavr.collection.HashMap.empty() + for (key in keys) { + map = map.put(key, "some element") + } + return map +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/vavrOrdered/Map.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/vavrOrdered/Map.kt new file mode 100644 index 00000000..c4936220 --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/vavrOrdered/Map.kt @@ -0,0 +1,169 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableMap.vavrOrdered + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = io.vavr.collection.LinkedHashMap.empty() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + + } + + @Benchmark + fun get(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentMap.get(keys[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentMap = io.vavr.collection.LinkedHashMap.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentMap = persistentMapPut(generateKeys(hashCodeType, size)) + } + + @Benchmark + fun iterateKeys(bh: Blackhole) { + for (k in persistentMap.keysIterator()) { + bh.consume(k) + } + } + + @Benchmark + fun iterateValues(bh: Blackhole) { + for (v in persistentMap.valuesIterator()) { + bh.consume(v) + } + } + + @Benchmark + fun iterateEntries(bh: Blackhole) { + for (e in persistentMap) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Put { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun put(): io.vavr.collection.LinkedHashMap { + return persistentMapPut(keys) + } + + @Benchmark + fun putAndGet(bh: Blackhole) { + val map = persistentMapPut(keys) + repeat(times = size) { index -> + bh.consume(map.get(keys[index])) + } + } + + @Benchmark + fun putAndIterateKeys(bh: Blackhole) { + val map = persistentMapPut(keys) + for (key in map.keysIterator()) { + bh.consume(key) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = io.vavr.collection.LinkedHashMap.empty() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun remove(): io.vavr.collection.LinkedHashMap { + var map = persistentMap + repeat(times = size) { index -> + map = map.remove(keys[index]) + } + return map + } +} + + +private fun persistentMapPut(keys: List): io.vavr.collection.LinkedHashMap { + var map = io.vavr.collection.LinkedHashMap.empty() + for (key in keys) { + map = map.put(key, "some element") + } + return map +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/vavrSorted/Map.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/vavrSorted/Map.kt new file mode 100644 index 00000000..452a9be6 --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableMap/vavrSorted/Map.kt @@ -0,0 +1,169 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableMap.vavrSorted + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = io.vavr.collection.TreeMap.empty() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + + } + + @Benchmark + fun get(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentMap.get(keys[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentMap = io.vavr.collection.TreeMap.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentMap = persistentMapPut(generateKeys(hashCodeType, size)) + } + + @Benchmark + fun iterateKeys(bh: Blackhole) { + for (k in persistentMap.keysIterator()) { + bh.consume(k) + } + } + + @Benchmark + fun iterateValues(bh: Blackhole) { + for (v in persistentMap.valuesIterator()) { + bh.consume(v) + } + } + + @Benchmark + fun iterateEntries(bh: Blackhole) { + for (e in persistentMap) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Put { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun put(): io.vavr.collection.TreeMap { + return persistentMapPut(keys) + } + + @Benchmark + fun putAndGet(bh: Blackhole) { + val map = persistentMapPut(keys) + repeat(times = size) { index -> + bh.consume(map.get(keys[index])) + } + } + + @Benchmark + fun putAndIterateKeys(bh: Blackhole) { + val map = persistentMapPut(keys) + for (key in map.keysIterator()) { + bh.consume(key) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf() + private var persistentMap = io.vavr.collection.TreeMap.empty() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun remove(): io.vavr.collection.TreeMap { + var map = persistentMap + repeat(times = size) { index -> + map = map.remove(keys[index]) + } + return map + } +} + + +private fun persistentMapPut(keys: List): io.vavr.collection.TreeMap { + var map = io.vavr.collection.TreeMap.empty() + for (key in keys) { + map = map.put(key, "some element") + } + return map +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/capsule/Set.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/capsule/Set.kt new file mode 100644 index 00000000..bd3143d7 --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/capsule/Set.kt @@ -0,0 +1,154 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableSet.capsule + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun add(): io.usethesource.capsule.Set.Immutable { + return persistentSetAdd(elements) + } + + @Benchmark + fun addAndContains(bh: Blackhole) { + val set = persistentSetAdd(elements) + repeat(times = size) { index -> + bh.consume(set.contains(elements[index])) + } + } + + @Benchmark + fun addAndIterate(bh: Blackhole) { + val set = persistentSetAdd(elements) + for (element in set) { + bh.consume(element) + } + } +} + + +@State(Scope.Thread) +open class Contains { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + private var persistentSet = io.usethesource.capsule.core.PersistentTrieSet.of() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun contains(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentSet.contains(elements[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentSet = io.usethesource.capsule.core.PersistentTrieSet.of() + + @Setup(Level.Trial) + fun prepare() { + persistentSet = persistentSetAdd(generateElements(hashCodeType, size)) + } + + @Benchmark + fun iterate(bh: Blackhole) { + for (e in persistentSet) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + private var persistentSet = io.usethesource.capsule.core.PersistentTrieSet.of() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun remove(): io.usethesource.capsule.Set.Immutable { + var set = persistentSet + repeat(times = size) { index -> + set = set.__remove(elements[index]) + } + return set + } +} + + +private fun persistentSetAdd(elements: List): io.usethesource.capsule.Set.Immutable { + var set = io.usethesource.capsule.core.PersistentTrieSet.of() + for (element in elements) { + set = set.__insert(element) + } + return set +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/capsule/builder/SetBuilder.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/capsule/builder/SetBuilder.kt new file mode 100644 index 00000000..c9a27188 --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/capsule/builder/SetBuilder.kt @@ -0,0 +1,182 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableSet.capsule.builder + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var elements = listOf() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun add(): io.usethesource.capsule.Set.Transient { + return persistentSetBuilderAdd(elements, immutablePercentage) + } + + @Benchmark + fun addAndContains(bh: Blackhole) { + val builder = persistentSetBuilderAdd(elements, immutablePercentage) + repeat(times = size) { index -> + bh.consume(builder.contains(elements[index])) + } + } + + + @Benchmark + fun addAndIterate(bh: Blackhole) { + val set = persistentSetBuilderAdd(elements, immutablePercentage) + for (element in set) { + bh.consume(element) + } + } +} + + +@State(Scope.Thread) +open class Contains { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var elements = listOf() + private var builder = io.usethesource.capsule.core.PersistentTrieSet.of().asTransient() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + builder = persistentSetBuilderAdd(elements, immutablePercentage) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun contains(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(builder.contains(elements[index])) + } + } +} + + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var builder = io.usethesource.capsule.core.PersistentTrieSet.of().asTransient() + + @Setup(Level.Trial) + fun prepare() { + val elements = generateElements(hashCodeType, size) + builder = persistentSetBuilderAdd(elements, immutablePercentage) + } + + @Benchmark + fun iterate(bh: Blackhole) { + for (e in builder) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var elements = listOf() + private var elementsToRemove = listOf() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + + elementsToRemove = if (hashCodeType == NON_EXISTING_HASH_CODE) { + generateElements(hashCodeType, size) + } else { + elements + } + } + + @Benchmark + fun addAndRemove(): io.usethesource.capsule.Set.Transient { + val builder = persistentSetBuilderAdd(elements, immutablePercentage) + repeat(times = size) { index -> + builder.__remove(elementsToRemove[index]) + } + return builder + } +} + + +private fun persistentSetBuilderAdd( + elements: List, + immutablePercentage: Double +): io.usethesource.capsule.Set.Transient { + val immutableSize = immutableSize(elements.size, immutablePercentage) + + var set = io.usethesource.capsule.core.PersistentTrieSet.of() + for (index in 0 until immutableSize) { + set = set.__insert(elements[index]) + } + + val builder = set.asTransient() + for (index in immutableSize until elements.size) { + builder.add(elements[index]) + } + + return builder +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/clojure/Set.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/clojure/Set.kt new file mode 100644 index 00000000..250ad636 --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/clojure/Set.kt @@ -0,0 +1,154 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableSet.clojure + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun add(): clojure.lang.PersistentHashSet { + return persistentSetAdd(elements) + } + + @Benchmark + fun addAndContains(bh: Blackhole) { + val set = persistentSetAdd(elements) + repeat(times = size) { index -> + bh.consume(set.contains(elements[index])) + } + } + + @Benchmark + fun addAndIterate(bh: Blackhole) { + val set = persistentSetAdd(elements) + for (element in set) { + bh.consume(element) + } + } +} + + +@State(Scope.Thread) +open class Contains { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + private var persistentSet = clojure.lang.PersistentHashSet.EMPTY + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun contains(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentSet.contains(elements[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentSet = clojure.lang.PersistentHashSet.EMPTY + + @Setup(Level.Trial) + fun prepare() { + persistentSet = persistentSetAdd(generateElements(hashCodeType, size)) + } + + @Benchmark + fun iterate(bh: Blackhole) { + for (e in persistentSet) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + private var persistentSet = clojure.lang.PersistentHashSet.EMPTY + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun remove(): clojure.lang.PersistentHashSet { + var set = persistentSet + repeat(times = size) { index -> + set = set.disjoin(elements[index]) as clojure.lang.PersistentHashSet + } + return set + } +} + + +private fun persistentSetAdd(elements: List): clojure.lang.PersistentHashSet { + var set = clojure.lang.PersistentHashSet.EMPTY + for (element in elements) { + set = set.cons(element) as clojure.lang.PersistentHashSet + } + return set +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/clojure/builder/SetBuilder.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/clojure/builder/SetBuilder.kt new file mode 100644 index 00000000..40e64495 --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/clojure/builder/SetBuilder.kt @@ -0,0 +1,149 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableSet.clojure.builder + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var elements = listOf() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun add(): clojure.lang.ATransientSet { + return persistentSetBuilderAdd(elements, immutablePercentage) + } + + @Benchmark + fun addAndContains(bh: Blackhole) { + val builder = persistentSetBuilderAdd(elements, immutablePercentage) + repeat(times = size) { index -> + bh.consume(builder.contains(elements[index])) + } + } + + +} + + +@State(Scope.Thread) +open class Contains { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var elements = listOf() + private var builder = clojure.lang.PersistentHashSet.EMPTY.asTransient() as clojure.lang.ATransientSet + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + builder = persistentSetBuilderAdd(elements, immutablePercentage) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun contains(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(builder.contains(elements[index])) + } + } +} + + + + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var elements = listOf() + private var elementsToRemove = listOf() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + + elementsToRemove = if (hashCodeType == NON_EXISTING_HASH_CODE) { + generateElements(hashCodeType, size) + } else { + elements + } + } + + @Benchmark + fun addAndRemove(): clojure.lang.ATransientSet { + val builder = persistentSetBuilderAdd(elements, immutablePercentage) + repeat(times = size) { index -> + builder.disjoin(elementsToRemove[index]) + } + return builder + } +} + + +private fun persistentSetBuilderAdd( + elements: List, + immutablePercentage: Double +): clojure.lang.ATransientSet { + val immutableSize = immutableSize(elements.size, immutablePercentage) + + var set = clojure.lang.PersistentHashSet.EMPTY + for (index in 0 until immutableSize) { + set = set.cons(elements[index]) as clojure.lang.PersistentHashSet + } + + val builder = set.asTransient() as clojure.lang.ATransientSet + for (index in immutableSize until elements.size) { + builder.conj(elements[index]) + } + + return builder +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/clojureSorted/Set.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/clojureSorted/Set.kt new file mode 100644 index 00000000..8d4ecfc7 --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/clojureSorted/Set.kt @@ -0,0 +1,154 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableSet.clojureSorted + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun add(): clojure.lang.PersistentTreeSet { + return persistentSetAdd(elements) + } + + @Benchmark + fun addAndContains(bh: Blackhole) { + val set = persistentSetAdd(elements) + repeat(times = size) { index -> + bh.consume(set.contains(elements[index])) + } + } + + @Benchmark + fun addAndIterate(bh: Blackhole) { + val set = persistentSetAdd(elements) + for (element in set) { + bh.consume(element) + } + } +} + + +@State(Scope.Thread) +open class Contains { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + private var persistentSet = clojure.lang.PersistentTreeSet.EMPTY + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun contains(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentSet.contains(elements[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentSet = clojure.lang.PersistentTreeSet.EMPTY + + @Setup(Level.Trial) + fun prepare() { + persistentSet = persistentSetAdd(generateElements(hashCodeType, size)) + } + + @Benchmark + fun iterate(bh: Blackhole) { + for (e in persistentSet) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + private var persistentSet = clojure.lang.PersistentTreeSet.EMPTY + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun remove(): clojure.lang.PersistentTreeSet { + var set = persistentSet + repeat(times = size) { index -> + set = set.disjoin(elements[index]) as clojure.lang.PersistentTreeSet + } + return set + } +} + + +private fun persistentSetAdd(elements: List): clojure.lang.PersistentTreeSet { + var set = clojure.lang.PersistentTreeSet.EMPTY + for (element in elements) { + set = set.cons(element) as clojure.lang.PersistentTreeSet + } + return set +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/cyclops/Set.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/cyclops/Set.kt new file mode 100644 index 00000000..9bee89aa --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/cyclops/Set.kt @@ -0,0 +1,154 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableSet.cyclops + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun add(): cyclops.data.HashSet { + return persistentSetAdd(elements) + } + + @Benchmark + fun addAndContains(bh: Blackhole) { + val set = persistentSetAdd(elements) + repeat(times = size) { index -> + bh.consume(set.contains(elements[index])) + } + } + + @Benchmark + fun addAndIterate(bh: Blackhole) { + val set = persistentSetAdd(elements) + for (element in set) { + bh.consume(element) + } + } +} + + +@State(Scope.Thread) +open class Contains { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + private var persistentSet = cyclops.data.HashSet.empty() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun contains(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentSet.contains(elements[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentSet = cyclops.data.HashSet.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentSet = persistentSetAdd(generateElements(hashCodeType, size)) + } + + @Benchmark + fun iterate(bh: Blackhole) { + for (e in persistentSet) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + private var persistentSet = cyclops.data.HashSet.empty() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun remove(): cyclops.data.HashSet { + var set = persistentSet + repeat(times = size) { index -> + set = set.removeValue(elements[index]) + } + return set + } +} + + +private fun persistentSetAdd(elements: List): cyclops.data.HashSet { + var set = cyclops.data.HashSet.empty() + for (element in elements) { + set = set.add(element) + } + return set +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/cyclopsSorted/Set.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/cyclopsSorted/Set.kt new file mode 100644 index 00000000..d727ea6b --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/cyclopsSorted/Set.kt @@ -0,0 +1,154 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableSet.cyclopsSorted + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun add(): cyclops.data.TreeSet { + return persistentSetAdd(elements) + } + + @Benchmark + fun addAndContains(bh: Blackhole) { + val set = persistentSetAdd(elements) + repeat(times = size) { index -> + bh.consume(set.contains(elements[index])) + } + } + + @Benchmark + fun addAndIterate(bh: Blackhole) { + val set = persistentSetAdd(elements) + for (element in set) { + bh.consume(element) + } + } +} + + +@State(Scope.Thread) +open class Contains { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + private var persistentSet = cyclops.data.TreeSet.empty() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun contains(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentSet.contains(elements[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentSet = cyclops.data.TreeSet.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentSet = persistentSetAdd(generateElements(hashCodeType, size)) + } + + @Benchmark + fun iterate(bh: Blackhole) { + for (e in persistentSet) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + private var persistentSet = cyclops.data.TreeSet.empty() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun remove(): cyclops.data.TreeSet { + var set = persistentSet + repeat(times = size) { index -> + set = set.removeValue(elements[index]) + } + return set + } +} + + +private fun persistentSetAdd(elements: List): cyclops.data.TreeSet { + var set = cyclops.data.TreeSet.empty() + for (element in elements) { + set = set.add(element) + } + return set +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/cyclopsTrie/Set.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/cyclopsTrie/Set.kt new file mode 100644 index 00000000..959122ab --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/cyclopsTrie/Set.kt @@ -0,0 +1,154 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableSet.cyclopsTrie + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun add(): cyclops.data.TrieSet { + return persistentSetAdd(elements) + } + + @Benchmark + fun addAndContains(bh: Blackhole) { + val set = persistentSetAdd(elements) + repeat(times = size) { index -> + bh.consume(set.contains(elements[index])) + } + } + + @Benchmark + fun addAndIterate(bh: Blackhole) { + val set = persistentSetAdd(elements) + for (element in set) { + bh.consume(element) + } + } +} + + +@State(Scope.Thread) +open class Contains { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + private var persistentSet = cyclops.data.TrieSet.empty() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun contains(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentSet.contains(elements[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentSet = cyclops.data.TrieSet.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentSet = persistentSetAdd(generateElements(hashCodeType, size)) + } + + @Benchmark + fun iterate(bh: Blackhole) { + for (e in persistentSet) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + private var persistentSet = cyclops.data.TrieSet.empty() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun remove(): cyclops.data.TrieSet { + var set = persistentSet + repeat(times = size) { index -> + set = set.removeValue(elements[index]) + } + return set + } +} + + +private fun persistentSetAdd(elements: List): cyclops.data.TrieSet { + var set = cyclops.data.TrieSet.empty() + for (element in elements) { + set = set.add(element) + } + return set +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/kotlin/Set.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/kotlin/Set.kt new file mode 100644 index 00000000..a1f533fa --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/kotlin/Set.kt @@ -0,0 +1,154 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableSet.kotlin + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun add(): kotlinx.collections.immutable.PersistentSet { + return persistentSetAdd(elements) + } + + @Benchmark + fun addAndContains(bh: Blackhole) { + val set = persistentSetAdd(elements) + repeat(times = size) { index -> + bh.consume(set.contains(elements[index])) + } + } + + @Benchmark + fun addAndIterate(bh: Blackhole) { + val set = persistentSetAdd(elements) + for (element in set) { + bh.consume(element) + } + } +} + + +@State(Scope.Thread) +open class Contains { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + private var persistentSet = kotlinx.collections.immutable.persistentHashSetOf() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun contains(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentSet.contains(elements[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentSet = kotlinx.collections.immutable.persistentHashSetOf() + + @Setup(Level.Trial) + fun prepare() { + persistentSet = persistentSetAdd(generateElements(hashCodeType, size)) + } + + @Benchmark + fun iterate(bh: Blackhole) { + for (e in persistentSet) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + private var persistentSet = kotlinx.collections.immutable.persistentHashSetOf() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun remove(): kotlinx.collections.immutable.PersistentSet { + var set = persistentSet + repeat(times = size) { index -> + set = set.remove(elements[index]) + } + return set + } +} + + +private fun persistentSetAdd(elements: List): kotlinx.collections.immutable.PersistentSet { + var set = kotlinx.collections.immutable.persistentHashSetOf() + for (element in elements) { + set = set.add(element) + } + return set +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/kotlin/builder/SetBuilder.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/kotlin/builder/SetBuilder.kt new file mode 100644 index 00000000..2de42747 --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/kotlin/builder/SetBuilder.kt @@ -0,0 +1,182 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableSet.kotlin.builder + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var elements = listOf() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun add(): kotlinx.collections.immutable.PersistentSet.Builder { + return persistentSetBuilderAdd(elements, immutablePercentage) + } + + @Benchmark + fun addAndContains(bh: Blackhole) { + val builder = persistentSetBuilderAdd(elements, immutablePercentage) + repeat(times = size) { index -> + bh.consume(builder.contains(elements[index])) + } + } + + + @Benchmark + fun addAndIterate(bh: Blackhole) { + val set = persistentSetBuilderAdd(elements, immutablePercentage) + for (element in set) { + bh.consume(element) + } + } +} + + +@State(Scope.Thread) +open class Contains { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var elements = listOf() + private var builder = kotlinx.collections.immutable.persistentHashSetOf().builder() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + builder = persistentSetBuilderAdd(elements, immutablePercentage) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun contains(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(builder.contains(elements[index])) + } + } +} + + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var builder = kotlinx.collections.immutable.persistentHashSetOf().builder() + + @Setup(Level.Trial) + fun prepare() { + val elements = generateElements(hashCodeType, size) + builder = persistentSetBuilderAdd(elements, immutablePercentage) + } + + @Benchmark + fun iterate(bh: Blackhole) { + for (e in builder) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var elements = listOf() + private var elementsToRemove = listOf() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + + elementsToRemove = if (hashCodeType == NON_EXISTING_HASH_CODE) { + generateElements(hashCodeType, size) + } else { + elements + } + } + + @Benchmark + fun addAndRemove(): kotlinx.collections.immutable.PersistentSet.Builder { + val builder = persistentSetBuilderAdd(elements, immutablePercentage) + repeat(times = size) { index -> + builder.remove(elementsToRemove[index]) + } + return builder + } +} + + +private fun persistentSetBuilderAdd( + elements: List, + immutablePercentage: Double +): kotlinx.collections.immutable.PersistentSet.Builder { + val immutableSize = immutableSize(elements.size, immutablePercentage) + + var set = kotlinx.collections.immutable.persistentHashSetOf() + for (index in 0 until immutableSize) { + set = set.add(elements[index]) + } + + val builder = set.builder() + for (index in immutableSize until elements.size) { + builder.add(elements[index]) + } + + return builder +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/kotlinOrdered/Set.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/kotlinOrdered/Set.kt new file mode 100644 index 00000000..0faeb0db --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/kotlinOrdered/Set.kt @@ -0,0 +1,154 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableSet.kotlinOrdered + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun add(): kotlinx.collections.immutable.PersistentSet { + return persistentSetAdd(elements) + } + + @Benchmark + fun addAndContains(bh: Blackhole) { + val set = persistentSetAdd(elements) + repeat(times = size) { index -> + bh.consume(set.contains(elements[index])) + } + } + + @Benchmark + fun addAndIterate(bh: Blackhole) { + val set = persistentSetAdd(elements) + for (element in set) { + bh.consume(element) + } + } +} + + +@State(Scope.Thread) +open class Contains { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + private var persistentSet = kotlinx.collections.immutable.persistentSetOf() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun contains(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentSet.contains(elements[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentSet = kotlinx.collections.immutable.persistentSetOf() + + @Setup(Level.Trial) + fun prepare() { + persistentSet = persistentSetAdd(generateElements(hashCodeType, size)) + } + + @Benchmark + fun iterate(bh: Blackhole) { + for (e in persistentSet) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + private var persistentSet = kotlinx.collections.immutable.persistentSetOf() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun remove(): kotlinx.collections.immutable.PersistentSet { + var set = persistentSet + repeat(times = size) { index -> + set = set.remove(elements[index]) + } + return set + } +} + + +private fun persistentSetAdd(elements: List): kotlinx.collections.immutable.PersistentSet { + var set = kotlinx.collections.immutable.persistentSetOf() + for (element in elements) { + set = set.add(element) + } + return set +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/kotlinOrdered/builder/SetBuilder.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/kotlinOrdered/builder/SetBuilder.kt new file mode 100644 index 00000000..b24f0a2c --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/kotlinOrdered/builder/SetBuilder.kt @@ -0,0 +1,182 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableSet.kotlinOrdered.builder + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var elements = listOf() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun add(): kotlinx.collections.immutable.PersistentSet.Builder { + return persistentSetBuilderAdd(elements, immutablePercentage) + } + + @Benchmark + fun addAndContains(bh: Blackhole) { + val builder = persistentSetBuilderAdd(elements, immutablePercentage) + repeat(times = size) { index -> + bh.consume(builder.contains(elements[index])) + } + } + + + @Benchmark + fun addAndIterate(bh: Blackhole) { + val set = persistentSetBuilderAdd(elements, immutablePercentage) + for (element in set) { + bh.consume(element) + } + } +} + + +@State(Scope.Thread) +open class Contains { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var elements = listOf() + private var builder = kotlinx.collections.immutable.persistentSetOf().builder() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + builder = persistentSetBuilderAdd(elements, immutablePercentage) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun contains(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(builder.contains(elements[index])) + } + } +} + + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var builder = kotlinx.collections.immutable.persistentSetOf().builder() + + @Setup(Level.Trial) + fun prepare() { + val elements = generateElements(hashCodeType, size) + builder = persistentSetBuilderAdd(elements, immutablePercentage) + } + + @Benchmark + fun iterate(bh: Blackhole) { + for (e in builder) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var elements = listOf() + private var elementsToRemove = listOf() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + + elementsToRemove = if (hashCodeType == NON_EXISTING_HASH_CODE) { + generateElements(hashCodeType, size) + } else { + elements + } + } + + @Benchmark + fun addAndRemove(): kotlinx.collections.immutable.PersistentSet.Builder { + val builder = persistentSetBuilderAdd(elements, immutablePercentage) + repeat(times = size) { index -> + builder.remove(elementsToRemove[index]) + } + return builder + } +} + + +private fun persistentSetBuilderAdd( + elements: List, + immutablePercentage: Double +): kotlinx.collections.immutable.PersistentSet.Builder { + val immutableSize = immutableSize(elements.size, immutablePercentage) + + var set = kotlinx.collections.immutable.persistentSetOf() + for (index in 0 until immutableSize) { + set = set.add(elements[index]) + } + + val builder = set.builder() + for (index in immutableSize until elements.size) { + builder.add(elements[index]) + } + + return builder +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/scala/Set.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/scala/Set.kt new file mode 100644 index 00000000..74caf33b --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/scala/Set.kt @@ -0,0 +1,154 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableSet.scala + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun add(): scala.collection.immutable.HashSet { + return persistentSetAdd(elements) + } + + @Benchmark + fun addAndContains(bh: Blackhole) { + val set = persistentSetAdd(elements) + repeat(times = size) { index -> + bh.consume(set.contains(elements[index])) + } + } + + @Benchmark + fun addAndIterate(bh: Blackhole) { + val set = persistentSetAdd(elements) + for (element in set) { + bh.consume(element) + } + } +} + + +@State(Scope.Thread) +open class Contains { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + private var persistentSet = scala.collection.immutable.`HashSet$`.`MODULE$`.empty() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun contains(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentSet.contains(elements[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentSet = scala.collection.immutable.`HashSet$`.`MODULE$`.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentSet = persistentSetAdd(generateElements(hashCodeType, size)) + } + + @Benchmark + fun iterate(bh: Blackhole) { + for (e in persistentSet) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + private var persistentSet = scala.collection.immutable.`HashSet$`.`MODULE$`.empty() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun remove(): scala.collection.immutable.HashSet { + var set = persistentSet + repeat(times = size) { index -> + set = set.excl(elements[index]) + } + return set + } +} + + +private fun persistentSetAdd(elements: List): scala.collection.immutable.HashSet { + var set = scala.collection.immutable.`HashSet$`.`MODULE$`.empty() + for (element in elements) { + set = set.incl(element) + } + return set +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/scalaSorted/Set.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/scalaSorted/Set.kt new file mode 100644 index 00000000..d19d0a8d --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/scalaSorted/Set.kt @@ -0,0 +1,154 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableSet.scalaSorted + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun add(): scala.collection.immutable.TreeSet { + return persistentSetAdd(elements) + } + + @Benchmark + fun addAndContains(bh: Blackhole) { + val set = persistentSetAdd(elements) + repeat(times = size) { index -> + bh.consume(set.contains(elements[index])) + } + } + + @Benchmark + fun addAndIterate(bh: Blackhole) { + val set = persistentSetAdd(elements) + for (element in set) { + bh.consume(element) + } + } +} + + +@State(Scope.Thread) +open class Contains { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + private var persistentSet = scala.collection.immutable.TreeSet(scala.math.Ordering.comparatorToOrdering(Comparator.naturalOrder())) + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun contains(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentSet.contains(elements[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentSet = scala.collection.immutable.TreeSet(scala.math.Ordering.comparatorToOrdering(Comparator.naturalOrder())) + + @Setup(Level.Trial) + fun prepare() { + persistentSet = persistentSetAdd(generateElements(hashCodeType, size)) + } + + @Benchmark + fun iterate(bh: Blackhole) { + for (e in persistentSet) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + private var persistentSet = scala.collection.immutable.TreeSet(scala.math.Ordering.comparatorToOrdering(Comparator.naturalOrder())) + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun remove(): scala.collection.immutable.TreeSet { + var set = persistentSet + repeat(times = size) { index -> + set = set.excl(elements[index]) + } + return set + } +} + + +private fun persistentSetAdd(elements: List): scala.collection.immutable.TreeSet { + var set = scala.collection.immutable.TreeSet(scala.math.Ordering.comparatorToOrdering(Comparator.naturalOrder())) + for (element in elements) { + set = set.incl(element) + } + return set +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/vavr/Set.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/vavr/Set.kt new file mode 100644 index 00000000..fd4939e6 --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/vavr/Set.kt @@ -0,0 +1,154 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableSet.vavr + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun add(): io.vavr.collection.HashSet { + return persistentSetAdd(elements) + } + + @Benchmark + fun addAndContains(bh: Blackhole) { + val set = persistentSetAdd(elements) + repeat(times = size) { index -> + bh.consume(set.contains(elements[index])) + } + } + + @Benchmark + fun addAndIterate(bh: Blackhole) { + val set = persistentSetAdd(elements) + for (element in set) { + bh.consume(element) + } + } +} + + +@State(Scope.Thread) +open class Contains { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + private var persistentSet = io.vavr.collection.HashSet.empty() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun contains(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentSet.contains(elements[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentSet = io.vavr.collection.HashSet.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentSet = persistentSetAdd(generateElements(hashCodeType, size)) + } + + @Benchmark + fun iterate(bh: Blackhole) { + for (e in persistentSet) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + private var persistentSet = io.vavr.collection.HashSet.empty() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun remove(): io.vavr.collection.HashSet { + var set = persistentSet + repeat(times = size) { index -> + set = set.remove(elements[index]) + } + return set + } +} + + +private fun persistentSetAdd(elements: List): io.vavr.collection.HashSet { + var set = io.vavr.collection.HashSet.empty() + for (element in elements) { + set = set.add(element) + } + return set +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/vavrOrdered/Set.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/vavrOrdered/Set.kt new file mode 100644 index 00000000..aef8d3b0 --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/vavrOrdered/Set.kt @@ -0,0 +1,154 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableSet.vavrOrdered + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun add(): io.vavr.collection.LinkedHashSet { + return persistentSetAdd(elements) + } + + @Benchmark + fun addAndContains(bh: Blackhole) { + val set = persistentSetAdd(elements) + repeat(times = size) { index -> + bh.consume(set.contains(elements[index])) + } + } + + @Benchmark + fun addAndIterate(bh: Blackhole) { + val set = persistentSetAdd(elements) + for (element in set) { + bh.consume(element) + } + } +} + + +@State(Scope.Thread) +open class Contains { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + private var persistentSet = io.vavr.collection.LinkedHashSet.empty() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun contains(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentSet.contains(elements[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentSet = io.vavr.collection.LinkedHashSet.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentSet = persistentSetAdd(generateElements(hashCodeType, size)) + } + + @Benchmark + fun iterate(bh: Blackhole) { + for (e in persistentSet) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + private var persistentSet = io.vavr.collection.LinkedHashSet.empty() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun remove(): io.vavr.collection.LinkedHashSet { + var set = persistentSet + repeat(times = size) { index -> + set = set.remove(elements[index]) + } + return set + } +} + + +private fun persistentSetAdd(elements: List): io.vavr.collection.LinkedHashSet { + var set = io.vavr.collection.LinkedHashSet.empty() + for (element in elements) { + set = set.add(element) + } + return set +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/vavrSorted/Set.kt b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/vavrSorted/Set.kt new file mode 100644 index 00000000..c9498706 --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/immutableSet/vavrSorted/Set.kt @@ -0,0 +1,154 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks.immutableSet.vavrSorted + +import org.openjdk.jmh.annotations.* +import java.util.concurrent.TimeUnit +import org.openjdk.jmh.infra.Blackhole +import benchmarks.* + +@State(Scope.Thread) +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun add(): io.vavr.collection.TreeSet { + return persistentSetAdd(elements) + } + + @Benchmark + fun addAndContains(bh: Blackhole) { + val set = persistentSetAdd(elements) + repeat(times = size) { index -> + bh.consume(set.contains(elements[index])) + } + } + + @Benchmark + fun addAndIterate(bh: Blackhole) { + val set = persistentSetAdd(elements) + for (element in set) { + bh.consume(element) + } + } +} + + +@State(Scope.Thread) +open class Contains { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + private var persistentSet = io.vavr.collection.TreeSet.empty() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun contains(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentSet.contains(elements[index])) + } + } +} + + +@State(Scope.Thread) +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentSet = io.vavr.collection.TreeSet.empty() + + @Setup(Level.Trial) + fun prepare() { + persistentSet = persistentSetAdd(generateElements(hashCodeType, size)) + } + + @Benchmark + fun iterate(bh: Blackhole) { + for (e in persistentSet) { + bh.consume(e) + } + } +} + + +@State(Scope.Thread) +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf() + private var persistentSet = io.vavr.collection.TreeSet.empty() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun remove(): io.vavr.collection.TreeSet { + var set = persistentSet + repeat(times = size) { index -> + set = set.remove(elements[index]) + } + return set + } +} + + +private fun persistentSetAdd(elements: List): io.vavr.collection.TreeSet { + var set = io.vavr.collection.TreeSet.empty() + for (element in elements) { + set = set.add(element) + } + return set +} diff --git a/benchmarks-libraries/src/jmh/java/benchmarks/utils.kt b/benchmarks-libraries/src/jmh/java/benchmarks/utils.kt new file mode 100644 index 00000000..c7382070 --- /dev/null +++ b/benchmarks-libraries/src/jmh/java/benchmarks/utils.kt @@ -0,0 +1,52 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Auto-generated file. DO NOT EDIT! + +package benchmarks + + +const val ASCENDING_HASH_CODE = "ascending" +const val RANDOM_HASH_CODE = "random" +const val COLLISION_HASH_CODE = "collision" +const val NON_EXISTING_HASH_CODE = "nonExisting" + +private inline fun intWrappers(size: Int, hashCodeGenerator: (index: Int) -> Int): List { + val keys = mutableListOf() + repeat(size) { + keys.add(IntWrapper(it, hashCodeGenerator(it))) + } + return keys +} + +private fun generateIntWrappers(hashCodeType: String, size: Int): List { + val random = java.util.Random(40) + return when(hashCodeType) { + ASCENDING_HASH_CODE -> intWrappers(size) { it } + RANDOM_HASH_CODE, + NON_EXISTING_HASH_CODE -> intWrappers(size) { random.nextInt() } + COLLISION_HASH_CODE -> intWrappers(size) { random.nextInt((size + 1) / 2) } + else -> throw AssertionError("Unknown hashCodeType: $hashCodeType") + } +} + +fun generateKeys(hashCodeType: String, size: Int) = generateIntWrappers(hashCodeType, size) +fun generateElements(hashCodeType: String, size: Int) = generateIntWrappers(hashCodeType, size) + + +fun immutableSize(size: Int, immutablePercentage: Double): Int { + return kotlin.math.floor(size * immutablePercentage / 100.0).toInt() +} diff --git a/benchmarks-libraries/src/main/kotlin/generators/CommonUtilsGenerator.kt b/benchmarks-libraries/src/main/kotlin/generators/CommonUtilsGenerator.kt new file mode 100644 index 00000000..156a4f8d --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/CommonUtilsGenerator.kt @@ -0,0 +1,62 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators + +import java.io.PrintWriter + +class CommonUtilsGenerator: SourceGenerator() { + override val outputFileName: String = "utils" + + override val imports: Set = setOf() + + override fun generateBody(out: PrintWriter) { + out.println(""" +const val ASCENDING_HASH_CODE = "ascending" +const val RANDOM_HASH_CODE = "random" +const val COLLISION_HASH_CODE = "collision" +const val NON_EXISTING_HASH_CODE = "nonExisting" + +private inline fun intWrappers(size: Int, hashCodeGenerator: (index: Int) -> Int): List { + val keys = mutableListOf() + repeat(size) { + keys.add(IntWrapper(it, hashCodeGenerator(it))) + } + return keys +} + +private fun generateIntWrappers(hashCodeType: String, size: Int): List { + val random = java.util.Random(40) + return when(hashCodeType) { + ASCENDING_HASH_CODE -> intWrappers(size) { it } + RANDOM_HASH_CODE, + NON_EXISTING_HASH_CODE -> intWrappers(size) { random.nextInt() } + COLLISION_HASH_CODE -> intWrappers(size) { random.nextInt((size + 1) / 2) } + else -> throw AssertionError("Unknown hashCodeType: ${"$"}hashCodeType") + } +} + +fun generateKeys(hashCodeType: String, size: Int) = generateIntWrappers(hashCodeType, size) +fun generateElements(hashCodeType: String, size: Int) = generateIntWrappers(hashCodeType, size) + + +fun immutableSize(size: Int, immutablePercentage: Double): Int { + return kotlin.math.floor(size * immutablePercentage / 100.0).toInt() +} + """.trimIndent() + ) + } +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/IntWrapperGenerator.kt b/benchmarks-libraries/src/main/kotlin/generators/IntWrapperGenerator.kt new file mode 100644 index 00000000..82707499 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/IntWrapperGenerator.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators + +import java.io.PrintWriter + +class IntWrapperGenerator: SourceGenerator() { + override val outputFileName: String = "IntWrapper" + + override val imports: Set = setOf() + + override fun generateBody(out: PrintWriter) { + out.println(""" +class IntWrapper(val obj: Int, val hashCode: Int) : Comparable { + override fun hashCode(): Int { + return hashCode + } + + override fun equals(other: Any?): Boolean { + if (other !is IntWrapper) { + return false + } + assert(obj != other.obj || hashCode == other.hashCode) // if elements are equal hashCodes must be equal + return obj == other.obj + } + + override fun compareTo(other: IntWrapper): Int { + return obj.compareTo(other.obj) + } +} + """.trimIndent() + ) + } +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/benchmarkSourceGenerator.kt b/benchmarks-libraries/src/main/kotlin/generators/benchmarkSourceGenerator.kt new file mode 100644 index 00000000..38562e62 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/benchmarkSourceGenerator.kt @@ -0,0 +1,210 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators + +import generators.immutableList.* +import generators.immutableList.impl.* +import generators.immutableListBuilder.* +import generators.immutableListBuilder.impl.* +import generators.immutableMap.* +import generators.immutableMap.impl.* +import generators.immutableMapBuilder.* +import generators.immutableMapBuilder.impl.* +import generators.immutableSet.* +import generators.immutableSet.impl.* +import generators.immutableSetBuilder.* +import generators.immutableSetBuilder.impl.* +import org.xml.sax.InputSource +import java.io.File +import java.io.PrintWriter +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.Paths +import javax.xml.xpath.XPathFactory + + +private const val BENCHMARKS_ROOT = "src/jmh/java/" + + +abstract class SourceGenerator { + abstract val outputFileName: String + open fun getPackage(): String = "benchmarks" + + fun generate(out: PrintWriter) { + out.println(readCopyrightNoticeFromProfile(File(".idea/copyright/apache_2_0.xml"))) + out.println("// Auto-generated file. DO NOT EDIT!") + out.println() + out.println("package ${getPackage()}") + out.println() + imports.forEach { + out.println("import $it") + } + out.println() + + generateBody(out) + } + + protected abstract val imports: Set + protected abstract fun generateBody(out: PrintWriter): Unit +} + +fun readCopyrightNoticeFromProfile(copyrightProfile: File): String { + val template = copyrightProfile.reader().use { reader -> + XPathFactory.newInstance().newXPath().evaluate("/component/copyright/option[@name='notice']/@value", InputSource(reader)) + } + val yearTemplate = "$today.year" + val year = java.time.LocalDate.now().year.toString() + assert(yearTemplate in template) + + return template.replace(yearTemplate, year).lines().joinToString("", prefix = "/*\n", postfix = " */\n") { " * $it\n" } +} + + +abstract class BenchmarkSourceGenerator: SourceGenerator() { + override val imports: Set = setOf( + "org.openjdk.jmh.annotations.*", + "java.util.concurrent.TimeUnit", + "org.openjdk.jmh.infra.Blackhole", + "benchmarks.*" + ) + + override fun generateBody(out: PrintWriter) { + generateBenchmark(out, "@State(Scope.Thread)") + } + + protected abstract fun generateBenchmark(out: PrintWriter, header: String) +} + + +private val listImpls = listOf( + KotlinListImplementation, + PaguroListImplementation, + CyclopsListImplementation, + ClojureListImplementation, + ScalaListImplementation, + VavrListImplementation +) +private val listBuilderImpls = listOf( + KotlinListBuilderImplementation, + PaguroListBuilderImplementation, + ClojureListBuilderImplementation +) + +private val mapImpls = listOf( + KotlinMapImplementation, + KotlinOrderedMapImplementation, + CapsuleMapImplementation, + PaguroMapImplementation, + PaguroSortedMapImplementation, + CyclopsMapImplementation, + CyclopsOrderedMapImplementation, + CyclopsTrieMapImplementation, + ClojureMapImplementation, + ClojureSortedMapImplementation, + ScalaMapImplementation, + ScalaSortedMapImplementation, + VavrMapImplementation, + VavrSortedMapImplementation, + VavrOrderedMapImplementation +) +private val mapBuilderImpls = listOf( + KotlinMapBuilderImplementation, + KotlinOrderedMapBuilderImplementation, + CapsuleMapBuilderImplementation, + PaguroMapBuilderImplementation, + ClojureMapBuilderImplementation +) + +private val setImpls = listOf( + KotlinSetImplementation, + KotlinOrderedSetImplementation, + CapsuleSetImplementation, + CyclopsSetImplementation, + CyclopsTrieSetImplementation, + CyclopsSortedSetImplementation, + ClojureSetImplementation, + ClojureSortedSetImplementation, + ScalaSetImplementation, + ScalaSortedSetImplementation, + VavrSetImplementation, + VavrSortedSetImplementation, + VavrOrderedSetImplementation +) +private val setBuilderImpls = listOf( + KotlinSetBuilderImplementation, + KotlinOrderedSetBuilderImplementation, + CapsuleSetBuilderImplementation, + ClojureSetBuilderImplementation +) + +fun generateBenchmarks() { + val listBenchmarks = listImpls.map { + ListBenchmarksGenerator(it) + } + val listBuilderBenchmarks = listBuilderImpls.map { + ListBuilderBenchmarksGenerator(it) + } + + val mapBenchmarks = mapImpls.map { + MapBenchmarksGenerator(it) + } + val mapBuilderBenchmarks = mapBuilderImpls.map { + MapBuilderBenchmarksGenerator(it) + } + + val setBenchmarks = setImpls.map { + SetBenchmarksGenerator(it) + } + val setBuilderBenchmarks = setBuilderImpls.map { + SetBuilderBenchmarksGenerator(it) + } + + val commonUtils = listOf( + IntWrapperGenerator(), + CommonUtilsGenerator() + ) + + + val allGenerators = listOf( + commonUtils, + listBenchmarks, + listBuilderBenchmarks, + mapBenchmarks, + mapBuilderBenchmarks, + setBenchmarks, + setBuilderBenchmarks + ).flatten() + + allGenerators.forEach { generator -> + val path = generator.getPackage().replace('.', '/') + "/" + generator.outputFileName + ".kt" + val file = File(BENCHMARKS_ROOT + path) + file.parentFile?.mkdirs() + val out = PrintWriter(file) + generator.generate(out) + out.flush() + } +} + + +fun main() { + Files.walk(Paths.get(BENCHMARKS_ROOT)) + .sorted(Comparator.reverseOrder()) + .map(Path::toFile) + .forEach { it.delete() } + + generateBenchmarks() +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/clojure.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/clojure.kt new file mode 100644 index 00000000..ad66639d --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/clojure.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableList.impl + +object ClojureListImplementation: ListImplementation { + override val packageName: String + = "clojure" + + override fun type(): String + = "clojure.lang.PersistentVector" + override fun empty(): String + = "clojure.lang.PersistentVector.EMPTY" + + override fun getOperation(list: String, index: String): String + = "$list.get($index)" + override fun setOperation(list: String, index: String, newValue: String): String + = "$list.assocN($index, $newValue)" + override fun addOperation(list: String, element: String): String + = "$list.cons($element)" + override fun removeLastOperation(list: String): String + = "$list.pop()" + + override fun iterateLastToFirst(list: String, size: String): String { + return """ + @Benchmark + fun lastToFirst(bh: Blackhole) { + val iterator = $list.listIterator($size) + + while (iterator.hasPrevious()) { + bh.consume(iterator.previous()) + } + }""" + } +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/cyclops.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/cyclops.kt new file mode 100644 index 00000000..db60c790 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/cyclops.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableList.impl + +object CyclopsListImplementation: ListImplementation { + override val packageName: String + = "cyclops" + + override fun type(): String + = "cyclops.data.Vector<$listElementType>" + override fun empty(): String + = "cyclops.data.Vector.empty<$listElementType>()" + + override fun getOperation(list: String, index: String): String + = "$list.get($index)" + override fun setOperation(list: String, index: String, newValue: String): String + = "$list.updateAt($index, $newValue)" + override fun addOperation(list: String, element: String): String + = "$list.plus($element)" + override fun removeLastOperation(list: String): String + = "$list.dropRight(1)" + + override fun iterateLastToFirst(list: String, size: String): String { + return """ + @Benchmark + fun lastToFirst(bh: Blackhole) { + val iterator = $list.reverse().iterator() + + while (iterator.hasNext()) { + bh.consume(iterator.next()) + } + }""" + } +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/kotlin.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/kotlin.kt new file mode 100644 index 00000000..8cb5f698 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/kotlin.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableList.impl + +object KotlinListImplementation: ListImplementation { + override val packageName: String + = "kotlin" + + override fun type(): String + = "kotlinx.collections.immutable.PersistentList<$listElementType>" + override fun empty(): String + = "kotlinx.collections.immutable.persistentListOf<$listElementType>()" + + override fun getOperation(list: String, index: String): String + = "$list.get($index)" + override fun setOperation(list: String, index: String, newValue: String): String + = "$list.set($index, $newValue)" + override fun addOperation(list: String, element: String): String + = "$list.add($element)" + override fun removeLastOperation(list: String): String + = "$list.removeAt($list.size - 1)" + + override fun iterateLastToFirst(list: String, size: String): String { + return """ + @Benchmark + fun lastToFirst(bh: Blackhole) { + val iterator = $list.listIterator($size) + + while (iterator.hasPrevious()) { + bh.consume(iterator.previous()) + } + }""" + } +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/listImplementation.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/listImplementation.kt new file mode 100644 index 00000000..22559509 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/listImplementation.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableList.impl + +interface ListImplementation { + val packageName: String + + fun type(): String + fun empty(): String + + fun getOperation(list: String, index: String): String + fun setOperation(list: String, index: String, newValue: String): String + fun addOperation(list: String, element: String): String + fun removeLastOperation(list: String): String + + fun iterateLastToFirst(list: String, size: String): String +} + +const val listElementType = "String" + +const val listElement = "\"some element\"" +const val listNewElement = "\"another element\"" \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/paguro.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/paguro.kt new file mode 100644 index 00000000..95301fd2 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/paguro.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableList.impl + +object PaguroListImplementation: ListImplementation { + override val packageName: String + = "paguro" + + override fun type(): String + = "org.organicdesign.fp.collections.RrbTree.ImRrbt<$listElementType>" + override fun empty(): String + = "org.organicdesign.fp.collections.RrbTree.empty<$listElementType>()" + + override fun getOperation(list: String, index: String): String + = "$list.get($index)" + override fun setOperation(list: String, index: String, newValue: String): String + = "$list.replace($index, $newValue)" + override fun addOperation(list: String, element: String): String + = "$list.append($element)" + override fun removeLastOperation(list: String): String + = "$list.without($list.size - 1)" + + override fun iterateLastToFirst(list: String, size: String): String { + return """ + @Benchmark + fun lastToFirst(bh: Blackhole) { + val iterator = $list.listIterator($size) + + while (iterator.hasPrevious()) { + bh.consume(iterator.previous()) + } + }""" + } +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/scala.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/scala.kt new file mode 100644 index 00000000..2ab72a79 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/scala.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableList.impl + +object ScalaListImplementation: ListImplementation { + override val packageName: String + = "scala" + + override fun type(): String + = "scala.collection.immutable.Vector<$listElementType>" + override fun empty(): String + = "scala.collection.immutable.`Vector\$`.`MODULE\$`.empty<$listElementType>()" + + override fun getOperation(list: String, index: String): String + = "$list.apply($index)" + override fun setOperation(list: String, index: String, newValue: String): String + = "$list.updateAt($index, $newValue)" + override fun addOperation(list: String, element: String): String + = "$list.appended($element) as " + type() + override fun removeLastOperation(list: String): String + = "$list.dropRight(1)" + + override fun iterateLastToFirst(list: String, size: String): String { + return """ + @Benchmark + fun lastToFirst(bh: Blackhole) { + val iterator = $list.reverseIterator() + + while (iterator.hasNext()) { + bh.consume(iterator.next()) + } + }""" + } +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/vavr.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/vavr.kt new file mode 100644 index 00000000..d5de3bc4 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableList/impl/vavr.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableList.impl + +object VavrListImplementation: ListImplementation { + override val packageName: String + = "vavr" + + override fun type(): String + = "io.vavr.collection.Vector<$listElementType>" + override fun empty(): String + = "io.vavr.collection.Vector.empty<$listElementType>()" + + override fun getOperation(list: String, index: String): String + = "$list.apply($index)" + override fun setOperation(list: String, index: String, newValue: String): String + = "$list.update($index, $newValue)" + override fun addOperation(list: String, element: String): String + = "$list.append($element)" + override fun removeLastOperation(list: String): String + = "$list.dropRight(1)" + + override fun iterateLastToFirst(list: String, size: String): String { + return """ + @Benchmark + fun lastToFirst(bh: Blackhole) { + val iterator = $list.reverseIterator() + + while (iterator.hasNext()) { + bh.consume(iterator.next()) + } + }""" + } +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableList/listBenchmarksGenerator.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableList/listBenchmarksGenerator.kt new file mode 100644 index 00000000..cd5f4cb3 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableList/listBenchmarksGenerator.kt @@ -0,0 +1,170 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableList + +import generators.BenchmarkSourceGenerator +import generators.immutableList.impl.ListImplementation +import generators.immutableList.impl.listElement +import generators.immutableList.impl.listNewElement +import java.io.PrintWriter + +class ListBenchmarksGenerator(private val impl: ListImplementation) : BenchmarkSourceGenerator() { + override val outputFileName: String get() = "List" + + override fun getPackage(): String { + return super.getPackage() + ".immutableList." + impl.packageName + } + + override fun generateBenchmark(out: PrintWriter, header: String) { + out.println(""" +$header +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Benchmark + fun addLast(): ${impl.type()} { + return persistentListAdd(size) + } + + @Benchmark + fun addLastAndIterate(bh: Blackhole) { + val list = persistentListAdd(size) + for (e in list) { + bh.consume(e) + } + } + + @Benchmark + fun addLastAndGet(bh: Blackhole) { + val list = persistentListAdd(size) + for (i in 0 until size) { + bh.consume(${impl.getOperation("list", "i")}) + } + } +} + + +$header +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = ${impl.empty()} + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + } + + @Benchmark + fun getByIndex(bh: Blackhole) { + for (i in 0 until size) { + bh.consume(${impl.getOperation("persistentList", "i")}) + } + } +} + + +$header +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = ${impl.empty()} + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + } + + @Benchmark + fun firstToLast(bh: Blackhole) { + for (e in persistentList) { + bh.consume(e) + } + } +${impl.iterateLastToFirst("persistentList", "size")} +} + + +$header +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = ${impl.empty()} + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + } + + @Benchmark + fun removeLast(): ${impl.type()} { + var list = persistentList + repeat(times = size) { + list = ${impl.removeLastOperation("list")} + } + return list + } +} + + +$header +open class Set { + @Param("10000", "100000") + var size: Int = 0 + + private var persistentList = ${impl.empty()} + private var randomIndices = listOf() + + @Setup(Level.Trial) + fun prepare() { + persistentList = persistentListAdd(size) + randomIndices = List(size) { it }.shuffled() + } + + @Benchmark + fun setByIndex(): ${impl.type()} { + repeat(times = size) { index -> + persistentList = ${impl.setOperation("persistentList", "index", listNewElement)} + } + return persistentList + } + + @Benchmark + fun setByRandomIndex(): ${impl.type()} { + repeat(times = size) { index -> + persistentList = ${impl.setOperation("persistentList", "randomIndices[index]", listNewElement)} + } + return persistentList + } +} + + +private fun persistentListAdd(size: Int): ${impl.type()} { + var list = ${impl.empty()} + repeat(times = size) { + list = ${impl.addOperation("list", listElement)} + } + return list +} + """.trimIndent() + ) + } +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableListBuilder/impl/clojure.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableListBuilder/impl/clojure.kt new file mode 100644 index 00000000..6fab7f70 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableListBuilder/impl/clojure.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableListBuilder.impl + +object ClojureListBuilderImplementation: ListBuilderImplementation { + override val packageName: String + = "clojure.builder" + + override fun type(): String + = "clojure.lang.ITransientVector" + override fun empty(): String + = "clojure.lang.PersistentVector.EMPTY.asTransient() as clojure.lang.ITransientVector" + + override fun getOperation(builder: String, index: String): String + = "$builder.valAt($index)" + override fun setOperation(builder: String, index: String, newValue: String): String + = "$builder.assocN($index, $newValue)" + override fun addOperation(builder: String, element: String): String + = "$builder.conj($element)" + override fun removeLastOperation(builder: String): String + = "$builder.pop()" + + override val isIterable: Boolean + = false + + override fun builderOperation(immutable: String): String + = "$immutable.asTransient() as clojure.lang.ITransientVector" + + override fun immutableEmpty(): String + = "clojure.lang.PersistentVector.EMPTY" + override fun immutableAddOperation(immutable: String, element: String): String + = "$immutable.cons($element)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableListBuilder/impl/kotlin.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableListBuilder/impl/kotlin.kt new file mode 100644 index 00000000..69ffcbc4 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableListBuilder/impl/kotlin.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableListBuilder.impl + +object KotlinListBuilderImplementation: ListBuilderImplementation { + override val packageName: String + = "kotlin.builder" + + override fun type(): String + = "kotlinx.collections.immutable.PersistentList.Builder<$listBuilderElementType>" + override fun empty(): String + = "kotlinx.collections.immutable.persistentListOf<$listBuilderElementType>().builder()" + + override fun getOperation(builder: String, index: String): String + = "$builder.get($index)" + override fun setOperation(builder: String, index: String, newValue: String): String + = "$builder.set($index, $newValue)" + override fun addOperation(builder: String, element: String): String + = "$builder.add($element)" + override fun removeLastOperation(builder: String): String + = "$builder.removeAt($builder.size - 1)" + + override val isIterable: Boolean + = true + + override fun builderOperation(immutable: String): String + = "$immutable.builder()" + + override fun immutableEmpty(): String + = "kotlinx.collections.immutable.persistentListOf<$listBuilderElementType>()" + override fun immutableAddOperation(immutable: String, element: String): String + = "$immutable.add($element)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableListBuilder/impl/listBuilderImplementation.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableListBuilder/impl/listBuilderImplementation.kt new file mode 100644 index 00000000..c46af5bc --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableListBuilder/impl/listBuilderImplementation.kt @@ -0,0 +1,41 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableListBuilder.impl + +interface ListBuilderImplementation { + val packageName: String + + fun type(): String + fun empty(): String + + fun getOperation(builder: String, index: String): String + fun setOperation(builder: String, index: String, newValue: String): String + fun addOperation(builder: String, element: String): String + fun removeLastOperation(builder: String): String + + val isIterable: Boolean + + fun builderOperation(immutable: String): String + + fun immutableEmpty(): String + fun immutableAddOperation(immutable: String, element: String): String +} + +const val listBuilderElementType = "String" + +const val listBuilderElement = "\"some element\"" +const val listBuilderNewElement = "\"another element\"" \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableListBuilder/impl/paguro.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableListBuilder/impl/paguro.kt new file mode 100644 index 00000000..a414a8e4 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableListBuilder/impl/paguro.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableListBuilder.impl + +object PaguroListBuilderImplementation: ListBuilderImplementation { + override val packageName: String + = "paguro.builder" + + override fun type(): String + = "org.organicdesign.fp.collections.RrbTree.MutableRrbt<$listBuilderElementType>" + override fun empty(): String + = "org.organicdesign.fp.collections.RrbTree.emptyMutable<$listBuilderElementType>()" + + override fun getOperation(builder: String, index: String): String + = "$builder.get($index)" + override fun setOperation(builder: String, index: String, newValue: String): String + = "$builder.replace($index, $newValue)" + override fun addOperation(builder: String, element: String): String + = "$builder.append($element)" + override fun removeLastOperation(builder: String): String + = "$builder.without($builder.size - 1)" + + override val isIterable: Boolean + = true + + override fun builderOperation(immutable: String): String + = "$immutable.mutable()" + + override fun immutableEmpty(): String + = "org.organicdesign.fp.collections.RrbTree.empty<$listBuilderElementType>()" + override fun immutableAddOperation(immutable: String, element: String): String + = "$immutable.append($element)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableListBuilder/listBuilderBenchmarksGenerator.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableListBuilder/listBuilderBenchmarksGenerator.kt new file mode 100644 index 00000000..0734767a --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableListBuilder/listBuilderBenchmarksGenerator.kt @@ -0,0 +1,202 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableListBuilder + +import generators.BenchmarkSourceGenerator +import generators.immutableListBuilder.impl.ListBuilderImplementation +import generators.immutableListBuilder.impl.listBuilderElement +import generators.immutableListBuilder.impl.listBuilderNewElement +import java.io.PrintWriter + +class ListBuilderBenchmarksGenerator(private val impl: ListBuilderImplementation) : BenchmarkSourceGenerator() { + override val outputFileName: String = "ListBuilder" + + override fun getPackage(): String { + return super.getPackage() + ".immutableList." + impl.packageName + } + + override fun generateBenchmark(out: PrintWriter, header: String) { + out.println(""" +$header +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + @Benchmark + fun addLast(): ${impl.type()} { + return persistentListBuilderAdd(size, immutablePercentage) + } + + @Benchmark + fun addLastAndGet(bh: Blackhole) { + val builder = persistentListBuilderAdd(size, immutablePercentage) + for (i in 0 until size) { + bh.consume(${impl.getOperation("builder", "i")}) + } + } + +${ +if (impl.isIterable) """ + @Benchmark + fun addLastAndIterate(bh: Blackhole) { + val builder = persistentListBuilderAdd(size, immutablePercentage) + for (e in builder) { + bh.consume(e) + } + }""" +else "" +} +} + + +$header +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var builder: ${impl.type()} = ${impl.empty()} + + @Setup(Level.Trial) + fun prepare() { + builder = persistentListBuilderAdd(size, immutablePercentage) + } + + @Benchmark + fun getByIndex(bh: Blackhole) { + for (i in 0 until size) { + bh.consume(${impl.getOperation("builder", "i")}) + } + } +} + + +${ +if (impl.isIterable) """ +$header +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var builder = ${impl.empty()} + + @Setup(Level.Trial) + fun prepare() { + builder = persistentListBuilderAdd(size, immutablePercentage) + } + + @Benchmark + fun firstToLast(bh: Blackhole) { + for (e in builder) { + bh.consume(e) + } + } + + @Benchmark + fun lastToFirst(bh: Blackhole) { + val iterator = builder.listIterator(size) + + while (iterator.hasPrevious()) { + bh.consume(iterator.previous()) + } + } +}""" +else "" +} + + +$header +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + @Benchmark + fun addAndRemoveLast(): ${impl.type()} { + val builder = persistentListBuilderAdd(size, immutablePercentage) + for (i in 0 until size) { + ${impl.removeLastOperation("builder")} + } + return builder + } +} + + +$header +open class Set { + @Param("10000", "100000") + var size: Int = 0 + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var builder = ${impl.empty()} + private var randomIndices = listOf() + + @Setup(Level.Trial) + fun prepare() { + builder = persistentListBuilderAdd(size, immutablePercentage) + randomIndices = List(size) { it }.shuffled() + } + + @Benchmark + fun setByIndex(): ${impl.type()} { + for (i in 0 until size) { + ${impl.setOperation("builder", "i", listBuilderNewElement)} + } + return builder + } + + @Benchmark + fun setByRandomIndex(): ${impl.type()} { + for (i in 0 until size) { + ${impl.setOperation("builder", "randomIndices[i]", listBuilderNewElement)} + } + return builder + } +} + + +private fun persistentListBuilderAdd(size: Int, immutablePercentage: Double): ${impl.type()} { + val immutableSize = immutableSize(size, immutablePercentage) + + var list = ${impl.immutableEmpty()} + repeat(times = immutableSize) { + list = ${impl.immutableAddOperation("list", listBuilderNewElement)} + } + + val builder = ${impl.builderOperation("list")} + repeat(times = size - immutableSize) { + ${impl.addOperation("builder", listBuilderElement)} + } + + return builder +} + """.trimIndent() + ) + } +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/capsule.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/capsule.kt new file mode 100644 index 00000000..c437c02e --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/capsule.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableMap.impl + +object CapsuleMapImplementation: MapImplementation { + override val packageName: String + = "capsule" + + override fun type(): String + = "io.usethesource.capsule.Map.Immutable<$mapKeyType, $mapValueType>" + override fun empty(): String + = "io.usethesource.capsule.core.PersistentTrieMap.of<$mapKeyType, $mapValueType>()" + + override fun keysOperation(map: String): String + = "$map.keys" + override fun valuesOperation(map: String): String + = "$map.values" + + override fun getOperation(map: String, key: String): String + = "$map.get($key)" + override fun putOperation(map: String, key: String, value: String): String + = "$map.__put($key, $value)" + override fun removeOperation(map: String, key: String): String + = "$map.__remove($key)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/clojure.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/clojure.kt new file mode 100644 index 00000000..da611d6e --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/clojure.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableMap.impl + +object ClojureMapImplementation: MapImplementation { + override val packageName: String + = "clojure" + + override fun type(): String + = "clojure.lang.PersistentHashMap" + override fun empty(): String + = "clojure.lang.PersistentHashMap.EMPTY" + + override fun keysOperation(map: String): String + = "$map.keys" + override fun valuesOperation(map: String): String + = "$map.values" + + override fun getOperation(map: String, key: String): String + = "$map.valAt($key)" + override fun putOperation(map: String, key: String, value: String): String + = "$map.assoc($key, $value) as clojure.lang.PersistentHashMap" + override fun removeOperation(map: String, key: String): String + = "$map.without($key) as clojure.lang.PersistentHashMap" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/clojureSorted.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/clojureSorted.kt new file mode 100644 index 00000000..2a5fe566 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/clojureSorted.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableMap.impl + +object ClojureSortedMapImplementation: MapImplementation { + override val packageName: String + = "clojureSorted" + + override fun type(): String + = "clojure.lang.PersistentTreeMap" + override fun empty(): String + = "clojure.lang.PersistentTreeMap.EMPTY" + + override fun keysOperation(map: String): String + = "$map.keys" + override fun valuesOperation(map: String): String + = "$map.values" + + override fun getOperation(map: String, key: String): String + = "$map.valAt($key)" + override fun putOperation(map: String, key: String, value: String): String + = "$map.assoc($key, $value)" + override fun removeOperation(map: String, key: String): String + = "$map.without($key)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/cyclops.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/cyclops.kt new file mode 100644 index 00000000..60500668 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/cyclops.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableMap.impl + +object CyclopsMapImplementation: MapImplementation { + override val packageName: String + = "cyclops" + + override fun type(): String + = "cyclops.data.HashMap<$mapKeyType, $mapValueType>" + override fun empty(): String + = "cyclops.data.HashMap.empty<$mapKeyType, $mapValueType>()" + + override fun keysOperation(map: String): String + = "$map.keys()" + override fun valuesOperation(map: String): String + = "$map.values()" + + override fun getOperation(map: String, key: String): String + = "$map.get($key)" + override fun putOperation(map: String, key: String, value: String): String + = "$map.put($key, $value)" + override fun removeOperation(map: String, key: String): String + = "$map.remove($key)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/cyclopsOrdered.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/cyclopsOrdered.kt new file mode 100644 index 00000000..0896ed58 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/cyclopsOrdered.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableMap.impl + +object CyclopsOrderedMapImplementation: MapImplementation { + override val packageName: String + = "cyclopsOrdered" + + override fun type(): String + = "cyclops.data.LinkedMap<$mapKeyType, $mapValueType>" + override fun empty(): String + = "cyclops.data.LinkedMap.empty<$mapKeyType, $mapValueType>()" + + override fun keysOperation(map: String): String + = "$map.keys()" + override fun valuesOperation(map: String): String + = "$map.values()" + + override fun getOperation(map: String, key: String): String + = "$map.get($key)" + override fun putOperation(map: String, key: String, value: String): String + = "$map.put($key, $value)" + override fun removeOperation(map: String, key: String): String + = "$map.remove($key)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/cyclopsTrie.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/cyclopsTrie.kt new file mode 100644 index 00000000..a5ef11b4 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/cyclopsTrie.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableMap.impl + +object CyclopsTrieMapImplementation: MapImplementation { + override val packageName: String + = "cyclopsTrie" + + override fun type(): String + = "cyclops.data.TrieMap<$mapKeyType, $mapValueType>" + override fun empty(): String + = "cyclops.data.TrieMap.empty<$mapKeyType, $mapValueType>()" + + override fun keysOperation(map: String): String + = "$map.keys()" + override fun valuesOperation(map: String): String + = "$map.values()" + + override fun getOperation(map: String, key: String): String + = "$map.get($key)" + override fun putOperation(map: String, key: String, value: String): String + = "$map.put($key, $value)" + override fun removeOperation(map: String, key: String): String + = "$map.remove($key)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/kotlin.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/kotlin.kt new file mode 100644 index 00000000..1fc51486 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/kotlin.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableMap.impl + +object KotlinMapImplementation: MapImplementation { + override val packageName: String + = "kotlin" + + override fun type(): String + = "kotlinx.collections.immutable.PersistentMap<$mapKeyType, $mapValueType>" + override fun empty(): String + = "kotlinx.collections.immutable.persistentHashMapOf<$mapKeyType, $mapValueType>()" + + override fun keysOperation(map: String): String + = "$map.keys" + override fun valuesOperation(map: String): String + = "$map.values" + + override fun getOperation(map: String, key: String): String + = "$map.get($key)" + override fun putOperation(map: String, key: String, value: String): String + = "$map.put($key, $value)" + override fun removeOperation(map: String, key: String): String + = "$map.remove($key)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/kotlinOrdered.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/kotlinOrdered.kt new file mode 100644 index 00000000..f2b89d32 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/kotlinOrdered.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableMap.impl + +object KotlinOrderedMapImplementation: MapImplementation { + override val packageName: String + = "kotlinOrdered" + + override fun type(): String + = "kotlinx.collections.immutable.PersistentMap<$mapKeyType, $mapValueType>" + override fun empty(): String + = "kotlinx.collections.immutable.persistentMapOf<$mapKeyType, $mapValueType>()" + + override fun keysOperation(map: String): String + = "$map.keys" + override fun valuesOperation(map: String): String + = "$map.values" + + override fun getOperation(map: String, key: String): String + = "$map.get($key)" + override fun putOperation(map: String, key: String, value: String): String + = "$map.put($key, $value)" + override fun removeOperation(map: String, key: String): String + = "$map.remove($key)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/mapImplementation.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/mapImplementation.kt new file mode 100644 index 00000000..ea506075 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/mapImplementation.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableMap.impl + +interface MapImplementation { + val packageName: String + + fun type(): String + fun empty(): String + + fun keysOperation(map: String): String + fun valuesOperation(map: String): String + + fun getOperation(map: String, key: String): String + fun putOperation(map: String, key: String, value: String): String + fun removeOperation(map: String, key: String): String +} + +const val mapKeyType = "IntWrapper" +const val mapValueType = "String" \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/paguro.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/paguro.kt new file mode 100644 index 00000000..2f95cf85 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/paguro.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableMap.impl + +object PaguroMapImplementation: MapImplementation { + override val packageName: String + = "paguro" + + override fun type(): String + = "org.organicdesign.fp.collections.PersistentHashMap<$mapKeyType, $mapValueType>" + override fun empty(): String + = "org.organicdesign.fp.collections.PersistentHashMap.empty<$mapKeyType, $mapValueType>()" + + override fun keysOperation(map: String): String + = "$map.keys" + override fun valuesOperation(map: String): String + = "$map.values" + + override fun getOperation(map: String, key: String): String + = "$map.get($key)" + override fun putOperation(map: String, key: String, value: String): String + = "$map.assoc($key, $value)" + override fun removeOperation(map: String, key: String): String + = "$map.without($key)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/paguroSorted.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/paguroSorted.kt new file mode 100644 index 00000000..48bb868a --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/paguroSorted.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableMap.impl + +object PaguroSortedMapImplementation: MapImplementation { + override val packageName: String + = "paguroSorted" + + override fun type(): String + = "org.organicdesign.fp.collections.PersistentTreeMap<$mapKeyType, $mapValueType>" + override fun empty(): String + = "org.organicdesign.fp.collections.PersistentTreeMap.empty<$mapKeyType, $mapValueType>()" + + override fun keysOperation(map: String): String + = "$map.keys" + override fun valuesOperation(map: String): String + = "$map.values" + + override fun getOperation(map: String, key: String): String + = "$map.get($key)" + override fun putOperation(map: String, key: String, value: String): String + = "$map.assoc($key, $value)" + override fun removeOperation(map: String, key: String): String + = "$map.without($key)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/scala.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/scala.kt new file mode 100644 index 00000000..3407d760 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/scala.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableMap.impl + +object ScalaMapImplementation: MapImplementation { + override val packageName: String + = "scala" + + override fun type(): String + = "scala.collection.immutable.HashMap<$mapKeyType, $mapValueType>" + override fun empty(): String + = "scala.collection.immutable.`HashMap\$`.`MODULE\$`.empty<$mapKeyType, $mapValueType>()" + + override fun keysOperation(map: String): String + = "$map.keys()" + override fun valuesOperation(map: String): String + = "$map.values()" + + override fun getOperation(map: String, key: String): String + = "$map.get($key)" + override fun putOperation(map: String, key: String, value: String): String + = "$map.updated($key, $value)" + override fun removeOperation(map: String, key: String): String + = "$map.removed($key)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/scalaSorted.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/scalaSorted.kt new file mode 100644 index 00000000..75c73296 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/scalaSorted.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableMap.impl + +object ScalaSortedMapImplementation: MapImplementation { + override val packageName: String + = "scalaSorted" + + override fun type(): String + = "scala.collection.immutable.TreeMap<$mapKeyType, $mapValueType>" + override fun empty(): String + = "scala.collection.immutable.`TreeMap\$`.`MODULE\$`.empty<$mapKeyType, $mapValueType>(scala.math.Ordering.comparatorToOrdering(Comparator.naturalOrder<$mapKeyType>()))" + + override fun keysOperation(map: String): String + = "$map.keys()" + override fun valuesOperation(map: String): String + = "$map.values()" + + override fun getOperation(map: String, key: String): String + = "$map.get($key)" + override fun putOperation(map: String, key: String, value: String): String + = "$map.updated($key, $value)" + override fun removeOperation(map: String, key: String): String + = "$map.removed($key)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/vavr.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/vavr.kt new file mode 100644 index 00000000..f65cbe47 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/vavr.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableMap.impl + +object VavrMapImplementation: MapImplementation { + override val packageName: String + = "vavr" + + override fun type(): String + = "io.vavr.collection.HashMap<$mapKeyType, $mapValueType>" + override fun empty(): String + = "io.vavr.collection.HashMap.empty<$mapKeyType, $mapValueType>()" + + override fun keysOperation(map: String): String + = "$map.keysIterator()" + override fun valuesOperation(map: String): String + = "$map.valuesIterator()" + + override fun getOperation(map: String, key: String): String + = "$map.get($key)" + override fun putOperation(map: String, key: String, value: String): String + = "$map.put($key, $value)" + override fun removeOperation(map: String, key: String): String + = "$map.remove($key)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/vavrOrdered.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/vavrOrdered.kt new file mode 100644 index 00000000..6fd60627 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/vavrOrdered.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableMap.impl + +object VavrOrderedMapImplementation: MapImplementation { + override val packageName: String + = "vavrOrdered" + + override fun type(): String + = "io.vavr.collection.LinkedHashMap<$mapKeyType, $mapValueType>" + override fun empty(): String + = "io.vavr.collection.LinkedHashMap.empty<$mapKeyType, $mapValueType>()" + + override fun keysOperation(map: String): String + = "$map.keysIterator()" + override fun valuesOperation(map: String): String + = "$map.valuesIterator()" + + override fun getOperation(map: String, key: String): String + = "$map.get($key)" + override fun putOperation(map: String, key: String, value: String): String + = "$map.put($key, $value)" + override fun removeOperation(map: String, key: String): String + = "$map.remove($key)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/vavrSorted.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/vavrSorted.kt new file mode 100644 index 00000000..c412fd85 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/impl/vavrSorted.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableMap.impl + +object VavrSortedMapImplementation: MapImplementation { + override val packageName: String + = "vavrSorted" + + override fun type(): String + = "io.vavr.collection.TreeMap<$mapKeyType, $mapValueType>" + override fun empty(): String + = "io.vavr.collection.TreeMap.empty<$mapKeyType, $mapValueType>()" + + override fun keysOperation(map: String): String + = "$map.keysIterator()" + override fun valuesOperation(map: String): String + = "$map.valuesIterator()" + + override fun getOperation(map: String, key: String): String + = "$map.get($key)" + override fun putOperation(map: String, key: String, value: String): String + = "$map.put($key, $value)" + override fun removeOperation(map: String, key: String): String + = "$map.remove($key)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableMap/mapBenchmarksGenerator.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/mapBenchmarksGenerator.kt new file mode 100644 index 00000000..dec41082 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableMap/mapBenchmarksGenerator.kt @@ -0,0 +1,180 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableMap + +import generators.BenchmarkSourceGenerator +import generators.immutableMap.impl.MapImplementation +import generators.immutableMap.impl.mapKeyType +import java.io.PrintWriter + +class MapBenchmarksGenerator(private val impl: MapImplementation) : BenchmarkSourceGenerator() { + override val outputFileName: String = "Map" + + override fun getPackage(): String { + return super.getPackage() + ".immutableMap." + impl.packageName + } + + override fun generateBenchmark(out: PrintWriter, header: String) { + out.println(""" +$header +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf<$mapKeyType>() + private var persistentMap = ${impl.empty()} + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + + } + + @Benchmark + fun get(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(${impl.getOperation("persistentMap", "keys[index]")}) + } + } +} + + +$header +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentMap = ${impl.empty()} + + @Setup(Level.Trial) + fun prepare() { + persistentMap = persistentMapPut(generateKeys(hashCodeType, size)) + } + + @Benchmark + fun iterateKeys(bh: Blackhole) { + for (k in ${impl.keysOperation("persistentMap")}) { + bh.consume(k) + } + } + + @Benchmark + fun iterateValues(bh: Blackhole) { + for (v in ${impl.valuesOperation("persistentMap")}) { + bh.consume(v) + } + } + + @Benchmark + fun iterateEntries(bh: Blackhole) { + for (e in persistentMap) { + bh.consume(e) + } + } +} + + +$header +open class Put { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf<$mapKeyType>() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun put(): ${impl.type()} { + return persistentMapPut(keys) + } + + @Benchmark + fun putAndGet(bh: Blackhole) { + val map = persistentMapPut(keys) + repeat(times = size) { index -> + bh.consume(${impl.getOperation("map", "keys[index]")}) + } + } + + @Benchmark + fun putAndIterateKeys(bh: Blackhole) { + val map = persistentMapPut(keys) + for (key in ${impl.keysOperation("map")}) { + bh.consume(key) + } + } +} + + +$header +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var keys = listOf<$mapKeyType>() + private var persistentMap = ${impl.empty()} + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + persistentMap = persistentMapPut(keys) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun remove(): ${impl.type()} { + var map = persistentMap + repeat(times = size) { index -> + map = ${impl.removeOperation("map", "keys[index]")} + } + return map + } +} + + +private fun persistentMapPut(keys: List<$mapKeyType>): ${impl.type()} { + var map = ${impl.empty()} + for (key in keys) { + map = ${impl.putOperation("map", "key", "\"some element\"")} + } + return map +} + """.trimIndent() + ) + } +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/impl/capsule.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/impl/capsule.kt new file mode 100644 index 00000000..b3491fc1 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/impl/capsule.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableMapBuilder.impl + +object CapsuleMapBuilderImplementation: MapBuilderImplementation { + override val packageName: String + = "capsule.builder" + + override fun type(): String + = "io.usethesource.capsule.Map.Transient<$mapBuilderKeyType, $mapBuilderValueType>" + override fun empty(): String + = "io.usethesource.capsule.core.PersistentTrieMap.of<$mapBuilderKeyType, $mapBuilderValueType>().asTransient()" + + override fun getOperation(builder: String, key: String): String + = "$builder.get($key)" + override fun putOperation(builder: String, key: String, value: String): String + = "$builder.put($key, $value)" + override fun removeOperation(builder: String, key: String): String + = "$builder.remove($key)" + + override val isIterable: Boolean + = true + + override fun builderOperation(immutable: String): String = + "$immutable.asTransient()" + + override fun immutableEmpty(): String + = "io.usethesource.capsule.core.PersistentTrieMap.of<$mapBuilderKeyType, $mapBuilderValueType>()" + override fun immutablePutOperation(immutable: String, key: String, value: String): String + = "$immutable.__put($key, $value)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/impl/clojure.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/impl/clojure.kt new file mode 100644 index 00000000..24c74d56 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/impl/clojure.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableMapBuilder.impl + +object ClojureMapBuilderImplementation: MapBuilderImplementation { + override val packageName: String + = "clojure.builder" + + override fun type(): String + = "clojure.lang.ATransientMap" + override fun empty(): String + = "clojure.lang.PersistentHashMap.EMPTY.asTransient() as clojure.lang.ATransientMap" + + override fun getOperation(builder: String, key: String): String + = "$builder.valAt($key)" + override fun putOperation(builder: String, key: String, value: String): String + = "$builder.assoc($key, $value)" + override fun removeOperation(builder: String, key: String): String + = "$builder.without($key)" + + override val isIterable: Boolean + = false + + override fun builderOperation(immutable: String): String + = "($immutable as clojure.lang.PersistentHashMap).asTransient() as clojure.lang.ATransientMap" + + override fun immutableEmpty(): String + = "clojure.lang.PersistentHashMap.EMPTY as clojure.lang.IPersistentMap" + override fun immutablePutOperation(immutable: String, key: String, value: String): String + = "$immutable.assoc($key, $value)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/impl/kotlin.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/impl/kotlin.kt new file mode 100644 index 00000000..873f7074 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/impl/kotlin.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableMapBuilder.impl + +object KotlinMapBuilderImplementation: MapBuilderImplementation { + override val packageName: String + = "kotlin.builder" + + override fun type(): String + = "kotlinx.collections.immutable.PersistentMap.Builder<$mapBuilderKeyType, $mapBuilderValueType>" + override fun empty(): String + = "kotlinx.collections.immutable.persistentHashMapOf<$mapBuilderKeyType, $mapBuilderValueType>().builder()" + + override fun getOperation(builder: String, key: String): String + = "$builder.get($key)" + override fun putOperation(builder: String, key: String, value: String): String + = "$builder.put($key, $value)" + override fun removeOperation(builder: String, key: String): String + = "$builder.remove($key)" + + override val isIterable: Boolean + = true + + override fun builderOperation(immutable: String): String = + "$immutable.builder()" + + override fun immutableEmpty(): String + = "kotlinx.collections.immutable.persistentHashMapOf<$mapBuilderKeyType, $mapBuilderValueType>()" + override fun immutablePutOperation(immutable: String, key: String, value: String): String + = "$immutable.put($key, $value)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/impl/kotlinOrdered.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/impl/kotlinOrdered.kt new file mode 100644 index 00000000..f1c91bd6 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/impl/kotlinOrdered.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableMapBuilder.impl + +object KotlinOrderedMapBuilderImplementation: MapBuilderImplementation { + override val packageName: String + = "kotlinOrdered.builder" + + override fun type(): String + = "kotlinx.collections.immutable.PersistentMap.Builder<$mapBuilderKeyType, $mapBuilderValueType>" + override fun empty(): String + = "kotlinx.collections.immutable.persistentMapOf<$mapBuilderKeyType, $mapBuilderValueType>().builder()" + + override fun getOperation(builder: String, key: String): String + = "$builder.get($key)" + override fun putOperation(builder: String, key: String, value: String): String + = "$builder.put($key, $value)" + override fun removeOperation(builder: String, key: String): String + = "$builder.remove($key)" + + override val isIterable: Boolean + = true + + override fun builderOperation(immutable: String): String = + "$immutable.builder()" + + override fun immutableEmpty(): String + = "kotlinx.collections.immutable.persistentMapOf<$mapBuilderKeyType, $mapBuilderValueType>()" + override fun immutablePutOperation(immutable: String, key: String, value: String): String + = "$immutable.put($key, $value)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/impl/mapBuilderImplementation.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/impl/mapBuilderImplementation.kt new file mode 100644 index 00000000..88a5d8f4 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/impl/mapBuilderImplementation.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableMapBuilder.impl + +interface MapBuilderImplementation { + val packageName: String + + fun type(): String + fun empty(): String + + fun getOperation(builder: String, key: String): String + fun putOperation(builder: String, key: String, value: String): String + fun removeOperation(builder: String, key: String): String + + val isIterable: Boolean + + fun builderOperation(immutable: String): String + + fun immutableEmpty(): String + fun immutablePutOperation(immutable: String, key: String, value: String): String +} + +const val mapBuilderKeyType: String = "IntWrapper" +const val mapBuilderValueType: String = "String" \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/impl/paguro.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/impl/paguro.kt new file mode 100644 index 00000000..9244fd77 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/impl/paguro.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableMapBuilder.impl + +object PaguroMapBuilderImplementation: MapBuilderImplementation { + override val packageName: String + = "paguro.builder" + + override fun type(): String + = "org.organicdesign.fp.collections.PersistentHashMap.MutableHashMap<$mapBuilderKeyType, $mapBuilderValueType>" + override fun empty(): String + = "org.organicdesign.fp.collections.PersistentHashMap.emptyMutable<$mapBuilderKeyType, $mapBuilderValueType>()" + + override fun getOperation(builder: String, key: String): String + = "$builder.get($key)" + override fun putOperation(builder: String, key: String, value: String): String + = "$builder.assoc($key, $value)" + override fun removeOperation(builder: String, key: String): String + = "$builder.without($key)" + + override val isIterable: Boolean + = true + + override fun builderOperation(immutable: String): String = + "$immutable.mutable()" + + override fun immutableEmpty(): String + = "org.organicdesign.fp.collections.PersistentHashMap.empty<$mapBuilderKeyType, $mapBuilderValueType>()" + override fun immutablePutOperation(immutable: String, key: String, value: String): String + = "$immutable.assoc($key, $value)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/mapBuilderBenchmarksGenerator.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/mapBuilderBenchmarksGenerator.kt new file mode 100644 index 00000000..2d2b7cdd --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableMapBuilder/mapBuilderBenchmarksGenerator.kt @@ -0,0 +1,213 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableMapBuilder + +import generators.BenchmarkSourceGenerator +import generators.immutableMapBuilder.impl.MapBuilderImplementation +import generators.immutableMapBuilder.impl.mapBuilderKeyType +import java.io.PrintWriter + +class MapBuilderBenchmarksGenerator(private val impl: MapBuilderImplementation) : BenchmarkSourceGenerator() { + override val outputFileName: String = "MapBuilder" + + override fun getPackage(): String { + return super.getPackage() + ".immutableMap." + impl.packageName + } + + override fun generateBenchmark(out: PrintWriter, header: String) { + out.println(""" +$header +open class Get { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var keys = listOf<$mapBuilderKeyType>() + private var builder = ${impl.empty()} + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + builder = persistentMapBuilderPut(keys, immutablePercentage) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun get(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(${impl.getOperation("builder", "keys[index]")}) + } + } +} + + +${ +if (impl.isIterable) """ +$header +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var builder = ${impl.empty()} + + @Setup(Level.Trial) + fun prepare() { + val keys = generateKeys(hashCodeType, size) + builder = persistentMapBuilderPut(keys, immutablePercentage) + } + + @Benchmark + fun iterateKeys(bh: Blackhole) { + for (k in builder.keys) { + bh.consume(k) + } + } + + @Benchmark + fun iterateValues(bh: Blackhole) { + for (v in builder.values) { + bh.consume(v) + } + } + + @Benchmark + fun iterateEntries(bh: Blackhole) { + for (e in builder) { + bh.consume(e) + } + } +}""" +else "" +} + + +$header +open class Put { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var keys = listOf<$mapBuilderKeyType>() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + } + + @Benchmark + fun put(): ${impl.type()} { + return persistentMapBuilderPut(keys, immutablePercentage) + } + + @Benchmark + fun putAndGet(bh: Blackhole) { + val builder = persistentMapBuilderPut(keys, immutablePercentage) + repeat(times = size) { index -> + bh.consume(${impl.getOperation("builder", "keys[index]")}) + } + } + +${ +if (impl.isIterable) """ + @Benchmark + fun putAndIterateKeys(bh: Blackhole) { + val builder = persistentMapBuilderPut(keys, immutablePercentage) + for (key in builder.keys) { + bh.consume(key) + } + }""" +else "" +} +} + + +$header +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var keys = listOf<$mapBuilderKeyType>() + private var keysToRemove = listOf<$mapBuilderKeyType>() + + @Setup(Level.Trial) + fun prepare() { + keys = generateKeys(hashCodeType, size) + + keysToRemove = if (hashCodeType == NON_EXISTING_HASH_CODE) { + generateKeys(hashCodeType, size) + } else { + keys + } + } + + @Benchmark + fun putAndRemove(): ${impl.type()} { + val builder = persistentMapBuilderPut(keys, immutablePercentage) + repeat(times = size) { index -> + ${impl.removeOperation("builder", "keysToRemove[index]")} + } + return builder + } +} + + +private fun persistentMapBuilderPut( + keys: List<$mapBuilderKeyType>, + immutablePercentage: Double +): ${impl.type()} { + val immutableSize = immutableSize(keys.size, immutablePercentage) + + var map = ${impl.immutableEmpty()} + for (index in 0 until immutableSize) { + map = ${impl.immutablePutOperation("map", "keys[index]", "\"some element\"")} + } + + val builder = ${impl.builderOperation("map")} + for (index in immutableSize until keys.size) { + ${impl.putOperation("builder", "keys[index]", "\"some element\"")} + } + + return builder +} + """.trimIndent() + ) + } +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/capsule.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/capsule.kt new file mode 100644 index 00000000..1ecc7b2a --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/capsule.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableSet.impl + +object CapsuleSetImplementation: SetImplementation { + override val packageName: String + = "capsule" + + override fun type(): String + = "io.usethesource.capsule.Set.Immutable<$setElementType>" + override fun empty(): String + = "io.usethesource.capsule.core.PersistentTrieSet.of<$setElementType>()" + + override fun addOperation(set: String, element: String): String + = "$set.__insert($element)" + override fun removeOperation(set: String, element: String): String + = "$set.__remove($element)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/clojure.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/clojure.kt new file mode 100644 index 00000000..50eed726 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/clojure.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableSet.impl + +object ClojureSetImplementation: SetImplementation { + override val packageName: String + = "clojure" + + override fun type(): String + = "clojure.lang.PersistentHashSet" + override fun empty(): String + = "clojure.lang.PersistentHashSet.EMPTY" + + override fun addOperation(set: String, element: String): String + = "$set.cons($element) as clojure.lang.PersistentHashSet" + override fun removeOperation(set: String, element: String): String + = "$set.disjoin($element) as clojure.lang.PersistentHashSet" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/clojureSorted.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/clojureSorted.kt new file mode 100644 index 00000000..7dec7237 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/clojureSorted.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableSet.impl + +object ClojureSortedSetImplementation: SetImplementation { + override val packageName: String + = "clojureSorted" + + override fun type(): String + = "clojure.lang.PersistentTreeSet" + override fun empty(): String + = "clojure.lang.PersistentTreeSet.EMPTY" + + override fun addOperation(set: String, element: String): String + = "$set.cons($element) as clojure.lang.PersistentTreeSet" + override fun removeOperation(set: String, element: String): String + = "$set.disjoin($element) as clojure.lang.PersistentTreeSet" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/cyclops.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/cyclops.kt new file mode 100644 index 00000000..9a30149e --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/cyclops.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableSet.impl + +object CyclopsSetImplementation: SetImplementation { + override val packageName: String + = "cyclops" + + override fun type(): String + = "cyclops.data.HashSet<$setElementType>" + override fun empty(): String + = "cyclops.data.HashSet.empty<$setElementType>()" + + override fun addOperation(set: String, element: String): String + = "$set.add($element)" + override fun removeOperation(set: String, element: String): String + = "$set.removeValue($element)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/cyclopsSorted.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/cyclopsSorted.kt new file mode 100644 index 00000000..f600b0a3 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/cyclopsSorted.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableSet.impl + +object CyclopsSortedSetImplementation: SetImplementation { + override val packageName: String + = "cyclopsSorted" + + override fun type(): String + = "cyclops.data.TreeSet<$setElementType>" + override fun empty(): String + = "cyclops.data.TreeSet.empty<$setElementType>()" + + override fun addOperation(set: String, element: String): String + = "$set.add($element)" + override fun removeOperation(set: String, element: String): String + = "$set.removeValue($element)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/cyclopsTrie.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/cyclopsTrie.kt new file mode 100644 index 00000000..94bb2148 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/cyclopsTrie.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableSet.impl + +object CyclopsTrieSetImplementation: SetImplementation { + override val packageName: String + = "cyclopsTrie" + + override fun type(): String + = "cyclops.data.TrieSet<$setElementType>" + override fun empty(): String + = "cyclops.data.TrieSet.empty<$setElementType>()" + + override fun addOperation(set: String, element: String): String + = "$set.add($element)" + override fun removeOperation(set: String, element: String): String + = "$set.removeValue($element)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/kotlin.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/kotlin.kt new file mode 100644 index 00000000..21bdd625 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/kotlin.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableSet.impl + +object KotlinSetImplementation: SetImplementation { + override val packageName: String + = "kotlin" + + override fun type(): String + = "kotlinx.collections.immutable.PersistentSet<$setElementType>" + override fun empty(): String + = "kotlinx.collections.immutable.persistentHashSetOf<$setElementType>()" + + override fun addOperation(set: String, element: String): String + = "$set.add($element)" + override fun removeOperation(set: String, element: String): String + = "$set.remove($element)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/kotlinOrdered.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/kotlinOrdered.kt new file mode 100644 index 00000000..3fe960cd --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/kotlinOrdered.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableSet.impl + +object KotlinOrderedSetImplementation: SetImplementation { + override val packageName: String + = "kotlinOrdered" + + override fun type(): String + = "kotlinx.collections.immutable.PersistentSet<$setElementType>" + override fun empty(): String + = "kotlinx.collections.immutable.persistentSetOf<$setElementType>()" + + override fun addOperation(set: String, element: String): String + = "$set.add($element)" + override fun removeOperation(set: String, element: String): String + = "$set.remove($element)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/scala.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/scala.kt new file mode 100644 index 00000000..fcdbf884 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/scala.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableSet.impl + +object ScalaSetImplementation: SetImplementation { + override val packageName: String + = "scala" + + override fun type(): String + = "scala.collection.immutable.HashSet<$setElementType>" + override fun empty(): String + = "scala.collection.immutable.`HashSet\$`.`MODULE$`.empty<$setElementType>()" + + override fun addOperation(set: String, element: String): String + = "$set.incl($element)" + override fun removeOperation(set: String, element: String): String + = "$set.excl($element)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/scalaSorted.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/scalaSorted.kt new file mode 100644 index 00000000..f1d83fdb --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/scalaSorted.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableSet.impl + +object ScalaSortedSetImplementation: SetImplementation { + override val packageName: String + = "scalaSorted" + + override fun type(): String + = "scala.collection.immutable.TreeSet<$setElementType>" + override fun empty(): String + = "scala.collection.immutable.TreeSet(scala.math.Ordering.comparatorToOrdering(Comparator.naturalOrder<$setElementType>()))" + + override fun addOperation(set: String, element: String): String + = "$set.incl($element)" + override fun removeOperation(set: String, element: String): String + = "$set.excl($element)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/setImplementation.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/setImplementation.kt new file mode 100644 index 00000000..b338a585 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/setImplementation.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableSet.impl + +interface SetImplementation { + val packageName: String + + fun type(): String + fun empty(): String + + fun addOperation(set: String, element: String): String + fun removeOperation(set: String, element: String): String +} + +const val setElementType = "IntWrapper" \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/vavr.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/vavr.kt new file mode 100644 index 00000000..01410511 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/vavr.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableSet.impl + +object VavrSetImplementation: SetImplementation { + override val packageName: String + = "vavr" + + override fun type(): String + = "io.vavr.collection.HashSet<$setElementType>" + override fun empty(): String + = "io.vavr.collection.HashSet.empty<$setElementType>()" + + override fun addOperation(set: String, element: String): String + = "$set.add($element)" + override fun removeOperation(set: String, element: String): String + = "$set.remove($element)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/vavrOrdered.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/vavrOrdered.kt new file mode 100644 index 00000000..b3ccf706 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/vavrOrdered.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableSet.impl + +object VavrOrderedSetImplementation: SetImplementation { + override val packageName: String + = "vavrOrdered" + + override fun type(): String + = "io.vavr.collection.LinkedHashSet<$setElementType>" + override fun empty(): String + = "io.vavr.collection.LinkedHashSet.empty<$setElementType>()" + + override fun addOperation(set: String, element: String): String + = "$set.add($element)" + override fun removeOperation(set: String, element: String): String + = "$set.remove($element)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/vavrSorted.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/vavrSorted.kt new file mode 100644 index 00000000..f37171a1 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/impl/vavrSorted.kt @@ -0,0 +1,32 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableSet.impl + +object VavrSortedSetImplementation: SetImplementation { + override val packageName: String + = "vavrSorted" + + override fun type(): String + = "io.vavr.collection.TreeSet<$setElementType>" + override fun empty(): String + = "io.vavr.collection.TreeSet.empty<$setElementType>()" + + override fun addOperation(set: String, element: String): String + = "$set.add($element)" + override fun removeOperation(set: String, element: String): String + = "$set.remove($element)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableSet/setBenchmarksGenerator.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/setBenchmarksGenerator.kt new file mode 100644 index 00000000..7135eb11 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableSet/setBenchmarksGenerator.kt @@ -0,0 +1,165 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableSet + +import generators.BenchmarkSourceGenerator +import generators.immutableSet.impl.SetImplementation +import generators.immutableSet.impl.setElementType +import java.io.PrintWriter + +class SetBenchmarksGenerator(private val impl: SetImplementation) : BenchmarkSourceGenerator() { + override val outputFileName: String = "Set" + + override fun getPackage(): String { + return super.getPackage() + ".immutableSet." + impl.packageName + } + + override fun generateBenchmark(out: PrintWriter, header: String) { + out.println(""" +$header +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf<$setElementType>() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun add(): ${impl.type()} { + return persistentSetAdd(elements) + } + + @Benchmark + fun addAndContains(bh: Blackhole) { + val set = persistentSetAdd(elements) + repeat(times = size) { index -> + bh.consume(set.contains(elements[index])) + } + } + + @Benchmark + fun addAndIterate(bh: Blackhole) { + val set = persistentSetAdd(elements) + for (element in set) { + bh.consume(element) + } + } +} + + +$header +open class Contains { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf<$setElementType>() + private var persistentSet = ${impl.empty()} + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun contains(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(persistentSet.contains(elements[index])) + } + } +} + + +$header +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + private var persistentSet = ${impl.empty()} + + @Setup(Level.Trial) + fun prepare() { + persistentSet = persistentSetAdd(generateElements(hashCodeType, size)) + } + + @Benchmark + fun iterate(bh: Blackhole) { + for (e in persistentSet) { + bh.consume(e) + } + } +} + + +$header +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + private var elements = listOf<$setElementType>() + private var persistentSet = ${impl.empty()} + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + persistentSet = persistentSetAdd(elements) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun remove(): ${impl.type()} { + var set = persistentSet + repeat(times = size) { index -> + set = ${impl.removeOperation("set", "elements[index]")} + } + return set + } +} + + +private fun persistentSetAdd(elements: List<$setElementType>): ${impl.type()} { + var set = ${impl.empty()} + for (element in elements) { + set = ${impl.addOperation("set", "element")} + } + return set +} + """.trimIndent() + ) + } +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableSetBuilder/impl/capsule.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableSetBuilder/impl/capsule.kt new file mode 100644 index 00000000..dcc7e51a --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableSetBuilder/impl/capsule.kt @@ -0,0 +1,43 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableSetBuilder.impl + +object CapsuleSetBuilderImplementation: SetBuilderImplementation { + override val packageName: String + = "capsule.builder" + + override fun type(): String + = "io.usethesource.capsule.Set.Transient<$setBuilderElementType>" + override fun empty(): String + = "io.usethesource.capsule.core.PersistentTrieSet.of<$setBuilderElementType>().asTransient()" + + override fun addOperation(builder: String, element: String): String + = "$builder.add($element)" + override fun removeOperation(builder: String, element: String): String + = "$builder.__remove($element)" + + override val isIterable: Boolean + = true + + override fun builderOperation(immutable: String): String + = "$immutable.asTransient()" + + override fun immutableEmpty(): String + = "io.usethesource.capsule.core.PersistentTrieSet.of<$setBuilderElementType>()" + override fun immutableAddOperation(immutable: String, element: String): String + = "$immutable.__insert($element)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableSetBuilder/impl/clojure.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableSetBuilder/impl/clojure.kt new file mode 100644 index 00000000..696bff3c --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableSetBuilder/impl/clojure.kt @@ -0,0 +1,43 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableSetBuilder.impl + +object ClojureSetBuilderImplementation: SetBuilderImplementation { + override val packageName: String + = "clojure.builder" + + override fun type(): String + = "clojure.lang.ATransientSet" + override fun empty(): String + = "clojure.lang.PersistentHashSet.EMPTY.asTransient() as clojure.lang.ATransientSet" + + override fun addOperation(builder: String, element: String): String + = "$builder.conj($element)" + override fun removeOperation(builder: String, element: String): String + = "$builder.disjoin($element)" + + override val isIterable: Boolean + = false + + override fun builderOperation(immutable: String): String + = "$immutable.asTransient() as clojure.lang.ATransientSet" + + override fun immutableEmpty(): String + = "clojure.lang.PersistentHashSet.EMPTY" + override fun immutableAddOperation(immutable: String, element: String): String + = "$immutable.cons($element) as clojure.lang.PersistentHashSet" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableSetBuilder/impl/kotlin.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableSetBuilder/impl/kotlin.kt new file mode 100644 index 00000000..1b0d9cc8 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableSetBuilder/impl/kotlin.kt @@ -0,0 +1,43 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableSetBuilder.impl + +object KotlinSetBuilderImplementation: SetBuilderImplementation { + override val packageName: String + = "kotlin.builder" + + override fun type(): String + = "kotlinx.collections.immutable.PersistentSet.Builder<$setBuilderElementType>" + override fun empty(): String + = "kotlinx.collections.immutable.persistentHashSetOf<$setBuilderElementType>().builder()" + + override fun addOperation(builder: String, element: String): String + = "$builder.add($element)" + override fun removeOperation(builder: String, element: String): String + = "$builder.remove($element)" + + override val isIterable: Boolean + = true + + override fun builderOperation(immutable: String): String + = "$immutable.builder()" + + override fun immutableEmpty(): String + = "kotlinx.collections.immutable.persistentHashSetOf<$setBuilderElementType>()" + override fun immutableAddOperation(immutable: String, element: String): String + = "$immutable.add($element)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableSetBuilder/impl/kotlinOrdered.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableSetBuilder/impl/kotlinOrdered.kt new file mode 100644 index 00000000..306aab42 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableSetBuilder/impl/kotlinOrdered.kt @@ -0,0 +1,43 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableSetBuilder.impl + +object KotlinOrderedSetBuilderImplementation: SetBuilderImplementation { + override val packageName: String + = "kotlinOrdered.builder" + + override fun type(): String + = "kotlinx.collections.immutable.PersistentSet.Builder<$setBuilderElementType>" + override fun empty(): String + = "kotlinx.collections.immutable.persistentSetOf<$setBuilderElementType>().builder()" + + override fun addOperation(builder: String, element: String): String + = "$builder.add($element)" + override fun removeOperation(builder: String, element: String): String + = "$builder.remove($element)" + + override val isIterable: Boolean + = true + + override fun builderOperation(immutable: String): String + = "$immutable.builder()" + + override fun immutableEmpty(): String + = "kotlinx.collections.immutable.persistentSetOf<$setBuilderElementType>()" + override fun immutableAddOperation(immutable: String, element: String): String + = "$immutable.add($element)" +} \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableSetBuilder/impl/setBuilderImplementation.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableSetBuilder/impl/setBuilderImplementation.kt new file mode 100644 index 00000000..dba55a43 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableSetBuilder/impl/setBuilderImplementation.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableSetBuilder.impl + +interface SetBuilderImplementation { + val packageName: String + + fun type(): String + fun empty(): String + + fun addOperation(builder: String, element: String): String + fun removeOperation(builder: String, element: String): String + + val isIterable: Boolean + + fun builderOperation(immutable: String): String + + fun immutableEmpty(): String + fun immutableAddOperation(immutable: String, element: String): String +} + +const val setBuilderElementType = "IntWrapper" \ No newline at end of file diff --git a/benchmarks-libraries/src/main/kotlin/generators/immutableSetBuilder/setBuilderBenchmarksGenerator.kt b/benchmarks-libraries/src/main/kotlin/generators/immutableSetBuilder/setBuilderBenchmarksGenerator.kt new file mode 100644 index 00000000..f7fa12c4 --- /dev/null +++ b/benchmarks-libraries/src/main/kotlin/generators/immutableSetBuilder/setBuilderBenchmarksGenerator.kt @@ -0,0 +1,199 @@ +/* + * Copyright 2016-2019 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package generators.immutableSetBuilder + +import generators.BenchmarkSourceGenerator +import generators.immutableSetBuilder.impl.SetBuilderImplementation +import generators.immutableSetBuilder.impl.setBuilderElementType +import java.io.PrintWriter + +class SetBuilderBenchmarksGenerator(private val impl: SetBuilderImplementation) : BenchmarkSourceGenerator() { + override val outputFileName: String = "SetBuilder" + + override fun getPackage(): String { + return super.getPackage() + ".immutableSet." + impl.packageName + } + + override fun generateBenchmark(out: PrintWriter, header: String) { + out.println(""" +$header +open class Add { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var elements = listOf<$setBuilderElementType>() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun add(): ${impl.type()} { + return persistentSetBuilderAdd(elements, immutablePercentage) + } + + @Benchmark + fun addAndContains(bh: Blackhole) { + val builder = persistentSetBuilderAdd(elements, immutablePercentage) + repeat(times = size) { index -> + bh.consume(builder.contains(elements[index])) + } + } + +${ +if (impl.isIterable) """ + @Benchmark + fun addAndIterate(bh: Blackhole) { + val set = persistentSetBuilderAdd(elements, immutablePercentage) + for (element in set) { + bh.consume(element) + } + }""" +else "" +} +} + + +$header +open class Contains { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var elements = listOf<$setBuilderElementType>() + private var builder = ${impl.empty()} + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + builder = persistentSetBuilderAdd(elements, immutablePercentage) + + if (hashCodeType == NON_EXISTING_HASH_CODE) + elements = generateElements(hashCodeType, size) + } + + @Benchmark + fun contains(bh: Blackhole) { + repeat(times = size) { index -> + bh.consume(builder.contains(elements[index])) + } + } +} + + +${ +if (impl.isIterable) """ +$header +open class Iterate { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var builder = ${impl.empty()} + + @Setup(Level.Trial) + fun prepare() { + val elements = generateElements(hashCodeType, size) + builder = persistentSetBuilderAdd(elements, immutablePercentage) + } + + @Benchmark + fun iterate(bh: Blackhole) { + for (e in builder) { + bh.consume(e) + } + } +}""" +else "" +} + + +$header +open class Remove { + @Param("10000", "100000") + var size: Int = 0 + + @Param(ASCENDING_HASH_CODE, RANDOM_HASH_CODE, COLLISION_HASH_CODE, NON_EXISTING_HASH_CODE) + var hashCodeType = "" + + @Param("0.0", "50.0") + var immutablePercentage: Double = 0.0 + + private var elements = listOf<$setBuilderElementType>() + private var elementsToRemove = listOf<$setBuilderElementType>() + + @Setup(Level.Trial) + fun prepare() { + elements = generateElements(hashCodeType, size) + + elementsToRemove = if (hashCodeType == NON_EXISTING_HASH_CODE) { + generateElements(hashCodeType, size) + } else { + elements + } + } + + @Benchmark + fun addAndRemove(): ${impl.type()} { + val builder = persistentSetBuilderAdd(elements, immutablePercentage) + repeat(times = size) { index -> + ${impl.removeOperation("builder", "elementsToRemove[index]")} + } + return builder + } +} + + +private fun persistentSetBuilderAdd( + elements: List<$setBuilderElementType>, + immutablePercentage: Double +): ${impl.type()} { + val immutableSize = immutableSize(elements.size, immutablePercentage) + + var set = ${impl.immutableEmpty()} + for (index in 0 until immutableSize) { + set = ${impl.immutableAddOperation("set", "elements[index]")} + } + + val builder = ${impl.builderOperation("set")} + for (index in immutableSize until elements.size) { + ${impl.addOperation("builder", "elements[index]")} + } + + return builder +} + """.trimIndent() + ) + } +} \ No newline at end of file