├── input.txt ├── .idea ├── .name ├── encodings.xml ├── compiler.xml ├── modules.xml └── misc.xml ├── Chapter09 ├── Cake.kt ├── NumberOfAvailableProcessors.kt ├── Lock.kt ├── Benchmarks.kt ├── Baker.kt ├── LaunchExample.kt ├── Bakery.kt └── suspendingSequence.kt ├── Chapter07 └── delegation │ ├── Calculator.java │ ├── kotlin │ ├── CalculatorBrain.kt │ ├── CalculatorMachine.kt │ ├── observable │ │ └── Main.kt │ ├── singleton │ │ └── Main.kt │ ├── generics │ │ └── Main.kt │ └── lazy │ │ └── Main.kt │ ├── CalculatorBrain.java │ ├── SuperCalculatorBrain.java │ ├── Main.java │ └── CalculatorMachine.java ├── Chapter01 ├── stringPool │ ├── Example2.kt │ ├── Example3.kt │ ├── Example4.kt │ ├── Example1.kt │ └── Example5.kt ├── .idea │ ├── modules.xml │ ├── chapter1.iml │ └── workspace.xml ├── memoryLeak │ ├── mutableKey │ │ ├── Example3.kt │ │ ├── Example1.kt │ │ └── Example2.kt │ ├── Example1.kt │ └── Example2.kt ├── tryFinally │ ├── Example3.kt │ ├── Example1.kt │ └── Example2.kt └── memoryModel │ └── Example1.kt ├── Chapter04 ├── Example4.kt ├── Example2.kt ├── Example3.kt └── Example1.kt ├── Chapter08 ├── Example2.kt ├── Example3.kt ├── Example1.kt ├── Example7.kt ├── Example4.kt ├── Example5.kt ├── Example6.kt ├── Benchmarks1.kt ├── Benchmarks2.kt └── Benchmarks3.kt ├── Chapter06 ├── Main.kt ├── constants │ └── Main.kt ├── lateinit │ └── Main.kt ├── Point.kt ├── backing │ ├── fields │ │ └── Button.kt │ └── properties │ │ └── Button.kt └── companion │ └── Example.kt ├── Chapter10 ├── higher_order_function │ ├── old │ │ ├── CompressionStrategy.java │ │ ├── ZipCompressionStrategy.java │ │ └── Archiver.java │ └── Archiver.kt ├── immutability │ └── Example1.kt └── actors │ └── Actors.kt ├── Chapter03 └── Example1.kt ├── Chapter05 ├── CollectionsEx.kt └── Benchmarks.kt ├── target └── classes │ └── mastering │ └── kotlin │ └── performance │ └── chapter1 │ └── .idea │ ├── modules.xml │ └── workspace.xml ├── Chapter02 └── benchmarking │ ├── example2 │ └── MyBenchmark.java │ ├── example6 │ └── MyBenchmark.java │ ├── example3 │ └── MyBenchmark.java │ ├── example1 │ └── MyBenchmark.java │ ├── example5 │ └── MyBenchmark.java │ └── example4 │ └── MyBenchmark.java ├── LICENSE ├── README.md └── pom.xml /input.txt: -------------------------------------------------------------------------------- 1 | Hello, Kotlin!!! -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | MasteringHighPerformanceWithKotlin -------------------------------------------------------------------------------- /Chapter09/Cake.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter9 2 | 3 | class Cake -------------------------------------------------------------------------------- /Chapter07/delegation/Calculator.java: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter7.delegation; 2 | 3 | public interface Calculator { 4 | int performOperation(String operand); 5 | } 6 | -------------------------------------------------------------------------------- /Chapter01/stringPool/Example2.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter1.stringPool 2 | 3 | fun main(vars: Array) { 4 | println(firstLine.intern() === firstLine.intern()) 5 | } -------------------------------------------------------------------------------- /Chapter04/Example4.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter4 2 | 3 | fun main(args: Array) { 4 | var counter = 0 5 | val inc = { 6 | counter ++ 7 | } 8 | inc() 9 | } -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Chapter04/Example2.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter4 2 | 3 | import kotlin.math.* 4 | 5 | fun main(vars: Array) { 6 | val minResult = min(3, 4) 7 | val sqrtResult = sqrt(9.0) 8 | } -------------------------------------------------------------------------------- /Chapter08/Example2.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter8 2 | 3 | fun main(args: Array) { 4 | val value = args[0].toDouble() 5 | if (value in 0.0..10.0) { 6 | println(value) 7 | } 8 | } -------------------------------------------------------------------------------- /Chapter08/Example3.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter8 2 | 3 | fun main(args: Array) { 4 | val value = args[0].toIntOrNull() 5 | if (value in 0..10) { 6 | println(value) 7 | } 8 | } -------------------------------------------------------------------------------- /Chapter08/Example1.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter8 2 | 3 | fun main(args: Array) { 4 | 5 | val int = args[0].toInt() 6 | 7 | if (int in 0..10) { 8 | println(int) 9 | } 10 | } -------------------------------------------------------------------------------- /Chapter08/Example7.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter8 2 | 3 | fun main(args: Array) { 4 | val value = args[0].toInt() 5 | 6 | if (value in (0..10).reversed()) { 7 | println(value) 8 | } 9 | } -------------------------------------------------------------------------------- /Chapter08/Example4.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter8 2 | 3 | fun main(args: Array) { 4 | val value: Char? = args[0].elementAtOrNull(0) 5 | if (value in 0.toChar()..10.toChar()) { 6 | println(value) 7 | } 8 | } -------------------------------------------------------------------------------- /Chapter09/NumberOfAvailableProcessors.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter9 2 | 3 | fun main(args: Array) { 4 | val number = Runtime.getRuntime().availableProcessors() 5 | println("Number of available processors: $number") 6 | } -------------------------------------------------------------------------------- /Chapter06/Main.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter6 2 | 3 | class Main { 4 | inner class Inner { 5 | fun printValue() { 6 | println(value) 7 | } 8 | } 9 | @JvmField 10 | var value = "Value" 11 | } -------------------------------------------------------------------------------- /Chapter10/higher_order_function/old/CompressionStrategy.java: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter10.higher_order_function.old; 2 | 3 | import java.io.File; 4 | 5 | public interface CompressionStrategy { 6 | File compress(File original); 7 | } 8 | -------------------------------------------------------------------------------- /Chapter06/constants/Main.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter6.constants 2 | 3 | import mastering.kotlin.performance.chapter6.Point 4 | 5 | val point = Point() 6 | const val compileTime: Int = 5 7 | fun compileTimeFunction() = compileTime + compileTime 8 | -------------------------------------------------------------------------------- /Chapter03/Example1.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter3 2 | 3 | class Tea 4 | 5 | class Coffee 6 | 7 | class Cup(val drink: T) 8 | 9 | fun main(vars: Array) { 10 | 11 | val cupOfTea = Cup(Tea()) 12 | 13 | val cupOfCoffee = Cup(Coffee()) 14 | } -------------------------------------------------------------------------------- /Chapter07/delegation/kotlin/CalculatorBrain.kt: -------------------------------------------------------------------------------- 1 | package delegation.kotlin 2 | 3 | import mastering.kotlin.performance.chapter7.delegation.Calculator 4 | 5 | 6 | class CalculatorBrain: Calculator { 7 | 8 | override fun performOperation(operand: String): Int = TODO() 9 | 10 | } -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Chapter05/CollectionsEx.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter5 2 | 3 | inline fun List.foreach(crossinline invoke: (T) -> Unit): Unit { 4 | val size = size 5 | var i = 0 6 | while (i < size) { 7 | invoke(get(i)) 8 | i ++ 9 | } 10 | } -------------------------------------------------------------------------------- /Chapter06/lateinit/Main.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter6.lateinit 2 | 3 | class Main { 4 | private lateinit var name: String 5 | fun onCreate() { 6 | name = "Jack" 7 | val name = this.name 8 | println(name) 9 | println(name) 10 | } 11 | } -------------------------------------------------------------------------------- /Chapter01/stringPool/Example3.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter1.stringPool 2 | 3 | fun main(vars: Array) { 4 | val cat1 = "Cat" 5 | val cat2 = "Cat" 6 | val cat3 = String("Cat".toCharArray()) 7 | 8 | println(cat1 === cat2) 9 | println(cat1 === cat3) 10 | } -------------------------------------------------------------------------------- /Chapter01/stringPool/Example4.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter1.stringPool 2 | 3 | fun main(vars: Array) { 4 | val cat1 = "Cat" 5 | val cat2 = cat1.plus("Dog") 6 | println(cat1) 7 | println(cat2) 8 | println(cat1 === cat2) 9 | println(cat1 === cat1) 10 | } -------------------------------------------------------------------------------- /Chapter01/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Chapter07/delegation/CalculatorBrain.java: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter7.delegation; 2 | 3 | public class CalculatorBrain implements Calculator { 4 | 5 | public int performOperation(String operand) { 6 | throw new IllegalStateException("Not implemented!"); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /Chapter07/delegation/SuperCalculatorBrain.java: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter7.delegation; 2 | 3 | public class SuperCalculatorBrain implements Calculator { 4 | @Override 5 | public int performOperation(String operand) { 6 | throw new IllegalStateException("not implemented"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Chapter06/Point.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter6 2 | 3 | data class Point(@JvmField var x: Int = 0, @JvmField var y: Int = 0) { 4 | var isTranslated = false 5 | fun translate(dx: Int, dy: Int) { 6 | this.x += dx 7 | this.y += dy 8 | this.isTranslated = true 9 | } 10 | } -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Chapter01/memoryLeak/mutableKey/Example3.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter1.memoryLeak.mutableKey 2 | 3 | fun main(vars: Array) { 4 | data class ImmutableKey(val name: String? = null) 5 | val map = HashMap() 6 | map[ImmutableKey("someName")] = 2 7 | print(map[ImmutableKey("someName")]) 8 | } -------------------------------------------------------------------------------- /Chapter01/memoryLeak/mutableKey/Example1.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter1.memoryLeak.mutableKey 2 | 3 | fun main(vars: Array) { 4 | 5 | class MutableKey(var name: String? = null) 6 | 7 | val map = HashMap() 8 | map[MutableKey("someName")] = 2 9 | print(map[MutableKey("someName")]) 10 | } -------------------------------------------------------------------------------- /Chapter01/tryFinally/Example3.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter1.tryFinally 2 | 3 | import java.io.File 4 | 5 | fun readFirstLine3(): String? = File("input.txt") 6 | .inputStream() 7 | .bufferedReader() 8 | .use { it.readLine() } 9 | 10 | fun main(args: Array) { 11 | println(readFirstLine3()) 12 | } -------------------------------------------------------------------------------- /Chapter07/delegation/Main.java: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter7.delegation; 2 | 3 | public class Main { 4 | public static void main(String[] args) { 5 | final CalculatorMachine calculatorMachine = new CalculatorMachine(new CalculatorBrain()); 6 | calculatorMachine.setDelegate(new SuperCalculatorBrain()); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /target/classes/mastering/kotlin/performance/chapter1/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Chapter07/delegation/kotlin/CalculatorMachine.kt: -------------------------------------------------------------------------------- 1 | package delegation.kotlin 2 | 3 | import mastering.kotlin.performance.chapter7.delegation.Calculator 4 | 5 | 6 | class CalculatorMachine(private val delegate: Calculator): Calculator by delegate { 7 | 8 | fun printDelagateClassName() { 9 | println(delegate::class.java.simpleName) 10 | } 11 | 12 | } -------------------------------------------------------------------------------- /Chapter10/higher_order_function/Archiver.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter10.higher_order_function 2 | 3 | import java.io.File 4 | 5 | fun File.archive(strategy: () -> File): File = strategy() 6 | 7 | fun main(args: Array) { 8 | File("input.txt").archive { TODO() }.also { 9 | // do something with an archived file 10 | } 11 | } -------------------------------------------------------------------------------- /Chapter01/stringPool/Example1.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter1.stringPool 2 | 3 | import java.io.File 4 | 5 | val firstLine: String 6 | get() = File("input.txt") 7 | .inputStream() 8 | .bufferedReader() 9 | .use { it.readLine() } 10 | 11 | fun main(vars: Array) { 12 | println(firstLine === firstLine) 13 | } -------------------------------------------------------------------------------- /Chapter09/Lock.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter9 2 | 3 | class Lock { 4 | 5 | private val lock = java.lang.Object() 6 | 7 | fun unlock() { 8 | synchronized(lock) { 9 | lock.notify() 10 | } 11 | } 12 | 13 | fun lock() { 14 | synchronized(lock) { 15 | lock.wait() 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /Chapter01/.idea/chapter1.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter01/memoryLeak/mutableKey/Example2.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter1.memoryLeak.mutableKey 2 | 3 | fun main(vars: Array) { 4 | 5 | data class MutableKey(var name: String? = null) 6 | 7 | val key = MutableKey("someName") 8 | 9 | val map = HashMap() 10 | map[key] = 2 11 | 12 | key.name = "anotherName" 13 | 14 | print(map[key]) 15 | } -------------------------------------------------------------------------------- /Chapter08/Example5.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter8 2 | 3 | fun main(args: Array) { 4 | val value = args[0].toInt() 5 | when(value) { 6 | in 100..200 -> println("Informational responses") 7 | in 200..300 -> println("Success") 8 | in 300..400 -> println("Redirection") 9 | in 400..500 -> println("Client error") 10 | in 500..600 -> println("Server error") 11 | } 12 | } -------------------------------------------------------------------------------- /Chapter09/Benchmarks.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter9 2 | 3 | import org.openjdk.jmh.annotations.* 4 | import java.util.concurrent.TimeUnit 5 | 6 | @BenchmarkMode(Mode.AverageTime) 7 | @OutputTimeUnit(TimeUnit.SECONDS) 8 | open class Benchmarks { 9 | 10 | @Benchmark 11 | fun order() = Bakery().order(amountOfCakes = 10) 12 | 13 | @Benchmark 14 | fun fastOrder() = Bakery().fastOrder(amountOfCakes = 10) 15 | 16 | } -------------------------------------------------------------------------------- /Chapter06/backing/fields/Button.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter6.backing.fields 2 | 3 | class Button { 4 | 5 | var text: String = TODO() 6 | set(value) { 7 | println(value) 8 | field = value 9 | } 10 | get() { 11 | return field + field 12 | } 13 | 14 | var backgroundColor: Int = TODO() 15 | 16 | var onClickListener: ((Button) -> Unit)? = null 17 | 18 | } -------------------------------------------------------------------------------- /Chapter08/Example6.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter8 2 | 3 | fun main(args: Array) { 4 | val value = args[0].toLong() 5 | when(value) { 6 | in 100L..200L -> println("Informational responses") 7 | in 200L..300L -> println("Success") 8 | in 300L..400L -> println("Redirection") 9 | in 400.0..500.0 -> println("Client error") 10 | in 500.0..600.0 -> println("Server error") 11 | } 12 | } -------------------------------------------------------------------------------- /Chapter10/higher_order_function/old/ZipCompressionStrategy.java: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter10.higher_order_function.old; 2 | 3 | import sun.reflect.generics.reflectiveObjects.NotImplementedException; 4 | import java.io.File; 5 | 6 | public class ZipCompressionStrategy implements CompressionStrategy { 7 | @Override 8 | public File compress(File original) { 9 | throw new NotImplementedException(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Chapter07/delegation/kotlin/observable/Main.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter7.delegation.kotlin.observable 2 | 3 | import kotlin.properties.Delegates 4 | 5 | var subject: String by Delegates.observable("init value") { 6 | property, old, new -> 7 | println("$old -> $new") 8 | } 9 | 10 | var maxLength: String by Delegates.vetoable("init value") { 11 | property, oldValue, newValue -> 12 | newValue.length > oldValue.length 13 | } -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Chapter10/immutability/Example1.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter10.immutability 2 | 3 | fun main(vars: Array) { 4 | data class ImmutableKey(val name: String? = null) 5 | val key = ImmutableKey() 6 | val copiedKey = key.copy() 7 | val copiedKeyWithAnotherName = key.copy(name = "AnotherName") 8 | println(key === copiedKey) 9 | println(key === copiedKeyWithAnotherName) 10 | println(key == copiedKey) 11 | println(key == copiedKeyWithAnotherName) 12 | } -------------------------------------------------------------------------------- /Chapter01/stringPool/Example5.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter1.stringPool 2 | 3 | class User(val id: Int = 0, val firstName: String = "", val lastName: String = "") 4 | 5 | fun main(vars: Array) { 6 | val user = User() 7 | val building = "304a" 8 | 9 | // val query = "SELECT id, firstName, lastName FROM Building " + building + " WHERE firstName = " + user.firstName 10 | val query = "SELECT id, firstName, lastName FROM Building $building WHERE firstName = ${user.firstName}" 11 | } -------------------------------------------------------------------------------- /Chapter04/Example3.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter4 2 | 3 | import java.io.File 4 | 5 | inline fun invokeBlock(body: () -> Unit) { 6 | try { 7 | body() 8 | } catch (e: Exception) { 9 | e.printStackTrace() 10 | } 11 | } 12 | 13 | fun main(args: Array) { 14 | 15 | val write = { 16 | val ints = listOf(1, 2, 3, 4, 5) 17 | File("somefile.txt") 18 | .writeText(ints.joinToString("\n")) 19 | } 20 | 21 | invokeBlock(write) 22 | 23 | invokeBlock(write) 24 | } -------------------------------------------------------------------------------- /Chapter01/tryFinally/Example1.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter1.tryFinally 2 | 3 | import java.io.BufferedReader 4 | import java.io.FileInputStream 5 | import java.io.InputStreamReader 6 | 7 | fun readFirstLine1() : String { 8 | val fileInputStream = FileInputStream("input.txt") 9 | val inputStreamReader = InputStreamReader(fileInputStream) 10 | val bufferedReader = BufferedReader(inputStreamReader) 11 | return bufferedReader.readLine() 12 | } 13 | 14 | fun main(args: Array) { 15 | println(readFirstLine1()) 16 | } -------------------------------------------------------------------------------- /Chapter09/Baker.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter9 2 | 3 | import io.reactivex.Single 4 | import io.reactivex.schedulers.Schedulers 5 | import java.math.BigInteger 6 | 7 | class Baker { 8 | 9 | fun bake(): Cake { 10 | for (i in 0..1_000_000_000) { 11 | BigInteger.ONE.modPow(BigInteger.TEN, BigInteger.TEN) 12 | } 13 | return Cake() 14 | } 15 | 16 | fun singleBake(): Single { 17 | return Single.fromCallable { bake() }.subscribeOn(Schedulers.computation()) 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /Chapter10/higher_order_function/old/Archiver.java: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter10.higher_order_function.old; 2 | 3 | import java.io.File; 4 | 5 | public class Archiver { 6 | private CompressionStrategy strategy; 7 | 8 | public CompressionStrategy getStrategy() { 9 | return strategy; 10 | } 11 | 12 | public void setStrategy(CompressionStrategy strategy) { 13 | this.strategy = strategy; 14 | } 15 | 16 | public File archive(File file) { 17 | return strategy.compress(file); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chapter06/backing/properties/Button.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter6.backing.properties 2 | 3 | class Button { 4 | 5 | private var _text: String? = null 6 | var text: String 7 | set(value) { 8 | println(value) 9 | _text = value 10 | } 11 | get() { 12 | return _text + _text 13 | } 14 | 15 | // var backgroundColor: Int? = null 16 | 17 | // var onClickListener: ((Button) -> Unit)? = null 18 | 19 | fun printText() { 20 | println(_text) 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /Chapter09/LaunchExample.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter9 2 | 3 | import kotlinx.coroutines.experimental.delay 4 | import kotlinx.coroutines.experimental.launch 5 | import kotlinx.coroutines.experimental.runBlocking 6 | import java.util.concurrent.TimeUnit 7 | 8 | fun main(args: Array) = runBlocking { 9 | val job = launch { 10 | val suspendLambda = suspend { 11 | delay(1, TimeUnit.SECONDS) 12 | println("Hello from suspend lambda") 13 | } 14 | suspendLambda() 15 | } 16 | job.join() 17 | } -------------------------------------------------------------------------------- /Chapter07/delegation/CalculatorMachine.java: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter7.delegation; 2 | 3 | public class CalculatorMachine implements Calculator { 4 | 5 | private Calculator delegate; 6 | 7 | public CalculatorMachine(Calculator delegate) { 8 | this.delegate = delegate; 9 | } 10 | 11 | public void setDelegate(Calculator delegate) { 12 | this.delegate = delegate; 13 | } 14 | 15 | @Override 16 | public int performOperation(String operand) { 17 | return delegate.performOperation(operand); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chapter06/companion/Example.kt: -------------------------------------------------------------------------------- 1 | // 2 | //@file:JvmName("Example") 3 | // 4 | //package mastering.kotlin.performance.chapter6.companion 5 | // 6 | //@JvmField 7 | //var prevId = -1 8 | // 9 | //class Example private constructor() { 10 | // 11 | // private var id: Int? = null 12 | // 13 | // companion object { 14 | // 15 | // @JvmStatic 16 | // fun newInstance(): mastering.kotlin.performance.chapter6.companion.Example { 17 | // val main = Example() 18 | // main.id = ++prevId 19 | // return main 20 | // } 21 | // } 22 | //} 23 | -------------------------------------------------------------------------------- /Chapter07/delegation/kotlin/singleton/Main.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter7.delegation.kotlin.singleton 2 | 3 | import kotlin.properties.ReadOnlyProperty 4 | import kotlin.reflect.KProperty 5 | 6 | object SingletonDelegate : ReadOnlyProperty { 7 | override fun getValue(thisRef: Any?, property: KProperty<*>): String? { 8 | return property.name 9 | } 10 | } 11 | 12 | class Main { 13 | val property by SingletonDelegate 14 | val another by SingletonDelegate 15 | } 16 | 17 | fun main(args: Array) { 18 | println(Main().property) 19 | } -------------------------------------------------------------------------------- /Chapter02/benchmarking/example2/MyBenchmark.java: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter2.benchmarking.example2; 2 | 3 | import org.openjdk.jmh.annotations.*; 4 | 5 | import java.util.concurrent.TimeUnit; 6 | 7 | public class MyBenchmark { 8 | 9 | @State(Scope.Thread) 10 | public static class MyState { 11 | int a = 3; 12 | int b = 4; 13 | } 14 | 15 | @Benchmark 16 | @BenchmarkMode(Mode.AverageTime) 17 | @OutputTimeUnit(TimeUnit.NANOSECONDS) 18 | public void testMethod(MyState myState) { 19 | int c = myState.a + myState.b; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Chapter02/benchmarking/example6/MyBenchmark.java: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter2.benchmarking.example6; 2 | 3 | import org.openjdk.jmh.annotations.*; 4 | 5 | import java.util.concurrent.TimeUnit; 6 | 7 | public class MyBenchmark { 8 | 9 | @State(Scope.Thread) 10 | public static class MyState { 11 | int a = 3; 12 | int b = 4; 13 | } 14 | 15 | @Benchmark 16 | @BenchmarkMode(Mode.AverageTime) 17 | @OutputTimeUnit(TimeUnit.NANOSECONDS) 18 | public int testMethod(MyState state) { 19 | return state.a + state.b; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /Chapter01/memoryModel/Example1.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter1.memoryModel 2 | 3 | import java.util.concurrent.Executors 4 | 5 | fun main(vars: Array) { 6 | var sharedVariableA = 0 7 | var sharedVariableB = 0 8 | val threadPool = Executors.newFixedThreadPool(10) 9 | val threadA = Runnable { 10 | sharedVariableA = 3 11 | sharedVariableB = 4 12 | } 13 | val threadB = Runnable { 14 | val localA = sharedVariableA 15 | val localB = sharedVariableB 16 | } 17 | threadPool.submit(threadA) 18 | threadPool.submit(threadB) 19 | } -------------------------------------------------------------------------------- /Chapter07/delegation/kotlin/generics/Main.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter7.delegation.kotlin.generics 2 | 3 | import kotlin.properties.ReadOnlyProperty 4 | import kotlin.reflect.KProperty 5 | 6 | class GenericDelegate : ReadOnlyProperty { 7 | override fun getValue(thisRef: Any?, property: KProperty<*>): T? { 8 | TODO() 9 | } 10 | } 11 | 12 | class Main { 13 | val property by IntDelegate() 14 | val another by GenericDelegate() 15 | } 16 | 17 | class IntDelegate : ReadOnlyProperty { 18 | 19 | override fun getValue(thisRef: Any?, property: KProperty<*>): Int? { 20 | TODO() 21 | } 22 | } -------------------------------------------------------------------------------- /Chapter04/Example1.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter4 2 | 3 | fun ex_1() { 4 | val numbers = listOf(1, 2, 3, 4, 5, 6, 7) 5 | val odds = ArrayList() 6 | for (i in 0..numbers.lastIndex) { 7 | val item = numbers[i] 8 | if (item % 2 != 0) { 9 | odds.add(item) 10 | } 11 | } 12 | } 13 | 14 | fun ex_2() { 15 | val numbers = listOf(1, 2, 3, 4, 5, 6, 7) 16 | val odds = numbers.filter { it % 2 != 0 } 17 | } 18 | 19 | fun ex_3() { 20 | val a = 3 21 | val b = 5 22 | val max = if (a > b) a else b 23 | } 24 | 25 | fun ex_4() { 26 | fun hasPrefix(x: Any) = when(x) { 27 | is String -> x.startsWith("prefix") 28 | else -> false 29 | } 30 | } -------------------------------------------------------------------------------- /Chapter02/benchmarking/example3/MyBenchmark.java: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter2.benchmarking.example3; 2 | 3 | import org.openjdk.jmh.annotations.*; 4 | 5 | @State(Scope.Thread) 6 | public class MyBenchmark { 7 | 8 | double x; 9 | 10 | @Setup 11 | public void prepare() { 12 | System.out.println("prepare"); 13 | x = Math.PI; 14 | } 15 | 16 | @TearDown 17 | public void check() { 18 | System.out.println("check"); 19 | assert x > Math.PI : "Nothing changed?"; 20 | } 21 | 22 | @Benchmark 23 | public void measureRight() { 24 | x++; 25 | } 26 | 27 | @Benchmark 28 | public void measureWrong() { 29 | double x = 0; 30 | x++; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Chapter01/memoryLeak/Example1.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter1.memoryLeak 2 | 3 | import io.reactivex.Observable 4 | import java.util.concurrent.TimeUnit 5 | 6 | fun main(vars: Array) { 7 | var memoryLeak: MemoryLeak? = MemoryLeak() 8 | memoryLeak?.start() 9 | memoryLeak = null 10 | memoryLeak = MemoryLeak() 11 | memoryLeak.start() 12 | Thread.currentThread().join() 13 | } 14 | 15 | class MemoryLeak { 16 | 17 | init { 18 | objectNumber ++ 19 | } 20 | 21 | private val currentObjectNumber = objectNumber 22 | 23 | fun start() { 24 | Observable.interval(1, TimeUnit.SECONDS) 25 | .subscribe { println(currentObjectNumber) } 26 | } 27 | 28 | companion object { 29 | @JvmField 30 | var objectNumber = 0 31 | } 32 | } -------------------------------------------------------------------------------- /Chapter07/delegation/kotlin/lazy/Main.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter7.delegation.kotlin.lazy 2 | 3 | import java.math.BigInteger 4 | 5 | class CacheThread(val lazyValue: BigInteger): Thread() { 6 | override fun run() { 7 | super.run() 8 | Thread.sleep(250) 9 | println("${this::class.java.simpleName} $lazyValue") 10 | } 11 | } 12 | 13 | class NetworkThread(val lazyValue: BigInteger): Thread() { 14 | override fun run() { 15 | super.run() 16 | Thread.sleep(300) 17 | println("${this::class.java.simpleName} $lazyValue") 18 | } 19 | } 20 | 21 | val lazyValue by lazy(LazyThreadSafetyMode.PUBLICATION) { 22 | println("computation") 23 | BigInteger.valueOf(2).modPow(BigInteger.valueOf(7), BigInteger.valueOf(20)) 24 | } 25 | 26 | fun main(args: Array) { 27 | CacheThread(lazyValue).start() 28 | NetworkThread(lazyValue).start() 29 | } -------------------------------------------------------------------------------- /Chapter01/tryFinally/Example2.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter1.tryFinally 2 | 3 | import java.io.BufferedReader 4 | import java.io.FileInputStream 5 | import java.io.InputStreamReader 6 | 7 | fun readFirstLine2() : String? { 8 | var fileInputStream: FileInputStream? = null 9 | var inputStreamReader: InputStreamReader? = null 10 | var bufferedReader: BufferedReader? = null 11 | return try { 12 | fileInputStream = FileInputStream("input.txt") 13 | inputStreamReader = InputStreamReader(fileInputStream) 14 | bufferedReader = BufferedReader(inputStreamReader) 15 | bufferedReader.readLine() 16 | } catch (e: Exception) { 17 | null 18 | } finally { 19 | fileInputStream?.close() 20 | inputStreamReader?.close() 21 | bufferedReader?.close() 22 | } 23 | } 24 | 25 | fun main(args: Array) { 26 | println(readFirstLine2()) 27 | } -------------------------------------------------------------------------------- /Chapter08/Benchmarks1.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter8 2 | 3 | import org.openjdk.jmh.annotations.Benchmark 4 | import org.openjdk.jmh.infra.Blackhole 5 | 6 | open class Benchmarks1 { 7 | val range = 0..1_000 8 | val array = Array(1_000) { it } 9 | 10 | @Benchmark 11 | fun rangeLoop(blackhole: Blackhole) { 12 | range.forEach { 13 | blackhole.consume(it) 14 | } 15 | } 16 | 17 | @Benchmark 18 | fun rangeSequenceLoop(blackhole: Blackhole) { 19 | range.asSequence().forEach { 20 | blackhole.consume(it) 21 | } 22 | } 23 | 24 | @Benchmark 25 | fun arrayLoop(blackhole: Blackhole) { 26 | array.forEach { 27 | blackhole.consume(it) 28 | } 29 | } 30 | 31 | @Benchmark 32 | fun arraySequenceLoop(blackhole: Blackhole) { 33 | array.asSequence().forEach { 34 | blackhole.consume(it) 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /Chapter01/memoryLeak/Example2.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter1.memoryLeak 2 | 3 | import io.reactivex.Observable 4 | import io.reactivex.disposables.Disposable 5 | import java.util.concurrent.TimeUnit 6 | 7 | fun main(vars: Array) { 8 | var memoryLeak: NoMemoryLeak? = NoMemoryLeak() 9 | memoryLeak?.start() 10 | memoryLeak?.disposable?.dispose() 11 | memoryLeak = NoMemoryLeak() 12 | memoryLeak.start() 13 | Thread.currentThread().join() 14 | } 15 | 16 | class NoMemoryLeak { 17 | 18 | init { 19 | objectNumber ++ 20 | } 21 | 22 | private val currentObjectNumber = objectNumber 23 | 24 | var disposable: Disposable? = null 25 | 26 | fun start() { 27 | disposable = Observable.interval(1, TimeUnit.SECONDS) 28 | .subscribe { println(currentObjectNumber) } 29 | } 30 | 31 | companion object { 32 | @JvmField 33 | var objectNumber = 0 34 | } 35 | } -------------------------------------------------------------------------------- /Chapter08/Benchmarks2.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter8 2 | 3 | import org.openjdk.jmh.annotations.Benchmark 4 | import org.openjdk.jmh.infra.Blackhole 5 | 6 | open class Benchmarks2 { 7 | val range = 0..1_000 8 | val array = Array(1_000) { it } 9 | 10 | @Benchmark 11 | fun rangeLoop(blackhole: Blackhole) 12 | = range 13 | .map { it * 2 } 14 | .first { it % 2 == 0 } 15 | 16 | 17 | @Benchmark 18 | fun rangeSequenceLoop(blackhole: Blackhole) 19 | = range.asSequence() 20 | .map { it * 2 } 21 | .first { it % 2 == 0 } 22 | 23 | @Benchmark 24 | fun arrayLoop(blackhole: Blackhole) 25 | = array 26 | .map { it * 2 } 27 | .first { it % 2 == 0 } 28 | 29 | @Benchmark 30 | fun arraySequenceLoop(blackhole: Blackhole) 31 | = array.asSequence() 32 | .map { it * 2 } 33 | .first { it % 2 == 0 } 34 | 35 | } -------------------------------------------------------------------------------- /Chapter02/benchmarking/example1/MyBenchmark.java: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter2.benchmarking.example1; 2 | 3 | import org.openjdk.jmh.annotations.Benchmark; 4 | import org.openjdk.jmh.annotations.Mode; 5 | import org.openjdk.jmh.runner.Runner; 6 | import org.openjdk.jmh.runner.RunnerException; 7 | import org.openjdk.jmh.runner.options.Options; 8 | import org.openjdk.jmh.runner.options.OptionsBuilder; 9 | 10 | public class MyBenchmark { 11 | 12 | @Benchmark 13 | public void testMethod() { 14 | int a = 3; 15 | int b = 4; 16 | int c = a + b; 17 | } 18 | 19 | public static void main(String[] args) throws RunnerException { 20 | Options opt = new OptionsBuilder() 21 | .include(MyBenchmark.class.getSimpleName()) 22 | .forks(1) 23 | .measurementIterations(1) 24 | .mode(Mode.AverageTime) 25 | .build(); 26 | 27 | new Runner(opt).run(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Chapter02/benchmarking/example5/MyBenchmark.java: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter2.benchmarking.example5; 2 | 3 | import org.openjdk.jmh.annotations.*; 4 | import org.openjdk.jmh.infra.Blackhole; 5 | 6 | import java.util.concurrent.TimeUnit; 7 | 8 | @BenchmarkMode(Mode.AverageTime) 9 | @OutputTimeUnit(TimeUnit.NANOSECONDS) 10 | @State(Scope.Thread) 11 | public class MyBenchmark { 12 | 13 | double x1 = Math.PI; 14 | double x2 = Math.PI * 2; 15 | 16 | @Benchmark 17 | public double baseline() { 18 | return Math.log(x1); 19 | } 20 | 21 | @Benchmark 22 | public double measureWrong() { 23 | Math.log(x1); 24 | return Math.log(x2); 25 | } 26 | 27 | @Benchmark 28 | public double measureRight_1() { 29 | return Math.log(x1) + Math.log(x2); 30 | } 31 | 32 | @Benchmark 33 | public void measureRight_2(Blackhole bh) { 34 | bh.consume(Math.log(x1)); 35 | bh.consume(Math.log(x2)); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /Chapter08/Benchmarks3.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter8 2 | 3 | import org.openjdk.jmh.annotations.* 4 | import org.openjdk.jmh.annotations.Benchmark 5 | import org.openjdk.jmh.infra.Blackhole 6 | 7 | 8 | open class Benchmarks3 { 9 | 10 | @State(Scope.Thread) 11 | open class MyState { 12 | val value = 3; 13 | } 14 | 15 | @Benchmark 16 | fun benchmark1(blackhole: Blackhole, state: MyState) { 17 | val range = 0..10 18 | 19 | if (state.value in range) { 20 | blackhole.consume(state.value) 21 | } 22 | 23 | if (state.value in range) { 24 | blackhole.consume(state.value) 25 | } 26 | } 27 | 28 | @Benchmark 29 | fun benchmark2(blackhole: Blackhole, state: MyState) { 30 | 31 | if (state.value in 0..10) { 32 | blackhole.consume(state.value) 33 | } 34 | 35 | if (state.value in 0..10) { 36 | blackhole.consume(state.value) 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Packt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Chapter02/benchmarking/example4/MyBenchmark.java: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter2.benchmarking.example4; 2 | 3 | import org.openjdk.jmh.annotations.*; 4 | 5 | import java.util.concurrent.TimeUnit; 6 | 7 | @State(Scope.Thread) 8 | @BenchmarkMode(Mode.AverageTime) 9 | @OutputTimeUnit(TimeUnit.NANOSECONDS) 10 | public class MyBenchmark { 11 | 12 | int x = 1; 13 | int y = 2; 14 | 15 | @Benchmark 16 | public int measureRight() { 17 | return (x + y); 18 | } 19 | 20 | private int reps(int reps) { 21 | int s = 0; 22 | for (int i = 0; i < reps; i++) { 23 | s += (x + y); 24 | } 25 | return s; 26 | } 27 | 28 | @Benchmark 29 | @OperationsPerInvocation(1) 30 | public int measureWrong_1() { 31 | return reps(1); 32 | } 33 | 34 | @Benchmark 35 | @OperationsPerInvocation(10) 36 | public int measureWrong_10() { 37 | return reps(10); 38 | } 39 | 40 | @Benchmark 41 | @OperationsPerInvocation(100) 42 | public int measureWrong_100() { 43 | return reps(100); 44 | } 45 | 46 | @Benchmark 47 | @OperationsPerInvocation(1000) 48 | public int measureWrong_1000() { 49 | return reps(1000); 50 | } 51 | 52 | @Benchmark 53 | @OperationsPerInvocation(10000) 54 | public int measureWrong_10000() { 55 | return reps(10000); 56 | } 57 | 58 | @Benchmark 59 | @OperationsPerInvocation(100000) 60 | public int measureWrong_100000() { 61 | return reps(100000); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /Chapter10/actors/Actors.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter10.actors 2 | 3 | import kotlinx.coroutines.experimental.CommonPool 4 | import kotlinx.coroutines.experimental.CompletableDeferred 5 | import kotlinx.coroutines.experimental.channels.actor 6 | import kotlinx.coroutines.experimental.launch 7 | import kotlinx.coroutines.experimental.runBlocking 8 | import kotlin.coroutines.experimental.CoroutineContext 9 | import kotlin.system.measureTimeMillis 10 | 11 | sealed class CounterMsg 12 | object IncCounter : CounterMsg() 13 | class GetCounter(val response: CompletableDeferred) : CounterMsg() 14 | 15 | fun counterActor() = actor { 16 | var counter = 0 // actor state 17 | for (msg in channel) { // iterate over incoming messages 18 | when (msg) { 19 | is IncCounter -> counter++ 20 | is GetCounter -> msg.response.complete(counter) 21 | } 22 | } 23 | } 24 | 25 | suspend fun massiveRun(context: CoroutineContext, action: suspend () -> Unit) { 26 | val n = 1000 // number of coroutines to launch 27 | val k = 1000 // times an action is repeated by each coroutine 28 | val time = measureTimeMillis { 29 | val jobs = List(n) { 30 | launch(context) { 31 | repeat(k) { action() } 32 | } 33 | } 34 | jobs.forEach { it.join() } 35 | } 36 | println("Completed ${n * k} actions in $time ms") 37 | } 38 | 39 | fun main(args: Array) = runBlocking { 40 | val counter = counterActor() 41 | massiveRun(CommonPool) { 42 | counter.send(IncCounter) 43 | } 44 | val response = CompletableDeferred() 45 | counter.send(GetCounter(response)) 46 | println("Counter = ${response.await()}") 47 | counter.close() 48 | } 49 | -------------------------------------------------------------------------------- /Chapter05/Benchmarks.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter5 2 | 3 | import org.openjdk.jmh.annotations.Benchmark 4 | import org.openjdk.jmh.annotations.BenchmarkMode 5 | import org.openjdk.jmh.annotations.Mode 6 | import org.openjdk.jmh.annotations.OutputTimeUnit 7 | import java.util.* 8 | import java.util.concurrent.TimeUnit 9 | 10 | class Student( 11 | val firstName: String, 12 | val secondName: String, 13 | val age: Int) 14 | 15 | val students = listOf( 16 | Student("Jacob", "Smith", 20), 17 | Student("Isabella", "Williams", 24), 18 | Student("Ava", "Johnson", 19), 19 | Student("Anthony", "Taylor", 18), 20 | Student("Elijah", "Davis", 17), 21 | Student("Daniel", "Moore", 24), 22 | Student("Ethan", "Thomas", 30), 23 | Student("Elijah", "Jackson", 25), 24 | Student("Jacob", "Anderson", 18), 25 | Student("Joshua", "Miller", 29), 26 | Student("Liam", "Davis", 22) 27 | ) 28 | 29 | @BenchmarkMode(Mode.AverageTime) 30 | @OutputTimeUnit(TimeUnit.SECONDS) 31 | open class Benchmarks { 32 | 33 | @Benchmark 34 | fun forEachIterator() { 35 | students.forEach { 36 | println(it.firstName) 37 | } 38 | } 39 | 40 | @Benchmark 41 | fun forEachWhile() { 42 | students.foreach { 43 | println(it.firstName) 44 | } 45 | } 46 | 47 | @Benchmark 48 | fun forEachLinkedListIterator() { 49 | LinkedList(students).forEach { 50 | println(it.firstName) 51 | } 52 | } 53 | 54 | @Benchmark 55 | fun forEachLinkedListWhile() { 56 | LinkedList(students).foreach { 57 | println(it.firstName) 58 | } 59 | } 60 | 61 | @Benchmark 62 | fun list() = (0..1_000_000) 63 | .filter { it % 2 == 0 } 64 | .map { it * it } 65 | .first() 66 | 67 | @Benchmark 68 | fun sequence() = (0..1_000_000) 69 | .asSequence() 70 | .filter { it % 2 == 0 } 71 | .map { it * it } 72 | .first() 73 | 74 | } -------------------------------------------------------------------------------- /Chapter09/Bakery.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter9 2 | 3 | import io.reactivex.* 4 | import kotlinx.coroutines.experimental.* 5 | import kotlinx.coroutines.experimental.channels.* 6 | import java.util.concurrent.CountDownLatch 7 | import java.util.concurrent.Executors 8 | import kotlinx.coroutines.experimental.rx2.await 9 | import kotlinx.coroutines.experimental.rx2.rxMaybe 10 | import java.util.concurrent.TimeUnit 11 | import kotlin.coroutines.experimental.* 12 | 13 | class Bakery { 14 | fun order(amountOfCakes: Int): List { 15 | val cakes = mutableListOf() 16 | val baker = Baker() 17 | val bakingTask = Runnable { 18 | cakes.add(baker.bake()) 19 | } 20 | for (i in 0 until amountOfCakes) { 21 | bakingTask.run() 22 | } 23 | return cakes 24 | } 25 | 26 | fun fastOrder(amountOfCakes: Int): List { 27 | val cakes = mutableListOf() 28 | val baker = Baker() 29 | val countDownLatch = CountDownLatch(amountOfCakes) 30 | val bakingTask = Runnable { 31 | cakes.add(baker.bake()) 32 | countDownLatch.countDown() 33 | } 34 | val executor = Executors.newFixedThreadPool(amountOfCakes) 35 | for (i in 0 until amountOfCakes) { 36 | executor.execute(bakingTask) 37 | } 38 | executor.shutdown() 39 | countDownLatch.await() 40 | return cakes 41 | } 42 | 43 | fun reactiveOrder(amountOfCakes: Int): Single> { 44 | val baker = Baker() 45 | return Observable.range(0, amountOfCakes) 46 | .flatMapSingle { baker.singleBake() } 47 | .toList() 48 | } 49 | 50 | suspend fun coroutinesOrder(amountOfCakes: Int): List { 51 | val baker = Baker() 52 | return (0 until amountOfCakes) 53 | .map { async { baker.bake() } } 54 | .map { it.await()} 55 | } 56 | 57 | fun coroutinesSequenceOrder(amountOfCakes: Int) = buildSequence { 58 | val baker = Baker() 59 | (0 until amountOfCakes) 60 | .forEach { yield(baker.bake()) } 61 | }.toList() 62 | 63 | suspend fun coroutinesSuspendingSequenceOrder(amountOfCakes: Int) = suspendingSequence { 64 | (0 until amountOfCakes) 65 | .map { async { Baker().bake() } } 66 | .forEach { yield(it.await()) } 67 | }.iterator().toList() 68 | 69 | suspend fun coroutinesProducerOrder(amountOfCakes: Int) = produce { 70 | (0 until amountOfCakes) 71 | .map { async { Baker().bake() } } 72 | .forEach { send(it.await()) } 73 | }.toList() 74 | 75 | suspend fun rxToCoroutinesOrder(amountOfCakes: Int): List { 76 | return reactiveOrder(amountOfCakes).await() 77 | } 78 | } 79 | 80 | //fun main(args: Array) = runBlocking { 81 | // val cakes = Bakery().rxToCoroutinesOrder(10) 82 | // println("Number of cakes: ${cakes.size}") 83 | //} 84 | 85 | 86 | //suspend fun sendString(channel: SendChannel, s: String, time: Long) { 87 | // // while (true) { 88 | // // delay(time) 89 | // channel.send(s) 90 | // // } 91 | //} 92 | // 93 | //fun main(args: Array) = runBlocking { 94 | // val channel = Channel() 95 | // // println(channel.toList()) 96 | // 97 | // launch { sendString(channel, "foo", 200L) } 98 | // launch { sendString(channel, "BAR!", 500L) } 99 | //} 100 | 101 | //fun main(args: Array) = runBlocking { 102 | // val cakes = Bakery().coroutinesOrder(10) 103 | // println("Number of cakes: ${cakes.size}") 104 | //} 105 | 106 | 107 | fun main(args: Array) = runBlocking { 108 | val cakes = Bakery().coroutinesOrder(amountOfCakes = 10) 109 | println("Number of cakes: ${cakes.size}") 110 | } 111 | 112 | //fun main(args: Array) { 113 | // val cakes = Bakery().fastOrder(amountOfCakes = 10) 114 | // println("Number of cakes: ${cakes.size}") 115 | //} 116 | 117 | //fun main(args: Array) { 118 | // Bakery().reactiveOrder(10) 119 | // .toObservable() 120 | // .blockingSubscribe { cakes -> println("Number of cakes: ${cakes.size}") } 121 | //} -------------------------------------------------------------------------------- /Chapter09/suspendingSequence.kt: -------------------------------------------------------------------------------- 1 | package mastering.kotlin.performance.chapter9 2 | 3 | import kotlinx.coroutines.experimental.async 4 | import kotlinx.coroutines.experimental.runBlocking 5 | import kotlin.coroutines.experimental.* 6 | 7 | interface SuspendingIterator { 8 | suspend operator fun hasNext(): Boolean 9 | suspend operator fun next(): T 10 | } 11 | 12 | suspend fun SuspendingIterator.toList(): List { 13 | val list = mutableListOf() 14 | while (this.hasNext()) { 15 | list.add(this.next()) 16 | } 17 | return list 18 | } 19 | 20 | interface SuspendingSequence { 21 | operator fun iterator(): SuspendingIterator 22 | } 23 | 24 | interface SuspendingSequenceBuilder { 25 | suspend fun yield(value: T) 26 | } 27 | 28 | class SuspendingIteratorCoroutine( 29 | override val context: CoroutineContext 30 | ): SuspendingIterator, SuspendingSequenceBuilder, Continuation { 31 | enum class State { INITIAL, COMPUTING_HAS_NEXT, COMPUTING_NEXT, COMPUTED, DONE } 32 | var state: State = State.INITIAL 33 | var nextValue: T? = null 34 | var nextStep: Continuation? = null // null when sequence complete 35 | 36 | // if (state == COMPUTING_NEXT) computeContinuation is Continuation 37 | // if (state == COMPUTING_HAS_NEXT) computeContinuation is Continuation 38 | var computeContinuation: Continuation<*>? = null 39 | 40 | suspend fun computeHasNext(): Boolean = suspendCoroutine { c -> 41 | state = State.COMPUTING_HAS_NEXT 42 | computeContinuation = c 43 | nextStep!!.resume(Unit) 44 | } 45 | 46 | suspend fun computeNext(): T = suspendCoroutine { c -> 47 | state = State.COMPUTING_NEXT 48 | computeContinuation = c 49 | nextStep!!.resume(Unit) 50 | } 51 | 52 | override suspend fun hasNext(): Boolean { 53 | when (state) { 54 | State.INITIAL -> return computeHasNext() 55 | State.COMPUTED -> return true 56 | State.DONE -> return false 57 | else -> throw IllegalStateException("Recursive dependency detected -- already computing next") 58 | } 59 | } 60 | 61 | override suspend fun next(): T { 62 | when (state) { 63 | State.INITIAL -> return computeNext() 64 | State.COMPUTED -> { 65 | state = State.INITIAL 66 | return nextValue as T 67 | } 68 | State.DONE -> throw NoSuchElementException() 69 | else -> throw IllegalStateException("Recursive dependency detected -- already computing next") 70 | } 71 | } 72 | 73 | @Suppress("UNCHECKED_CAST") 74 | fun resumeIterator(hasNext: Boolean) { 75 | when (state) { 76 | State.COMPUTING_HAS_NEXT -> { 77 | state = State.COMPUTED 78 | (computeContinuation as Continuation).resume(hasNext) 79 | } 80 | State.COMPUTING_NEXT -> { 81 | state = State.INITIAL 82 | (computeContinuation as Continuation).resume(nextValue as T) 83 | } 84 | else -> throw IllegalStateException("Was not supposed to be computing next value. Spurious yield?") 85 | } 86 | } 87 | 88 | // Completion continuation implementation 89 | override fun resume(value: Unit) { 90 | nextStep = null 91 | resumeIterator(false) 92 | } 93 | 94 | override fun resumeWithException(exception: Throwable) { 95 | nextStep = null 96 | state = State.DONE 97 | computeContinuation!!.resumeWithException(exception) 98 | } 99 | 100 | // Generator implementation 101 | override suspend fun yield(value: T): Unit = suspendCoroutine { c -> 102 | nextValue = value 103 | nextStep = c 104 | resumeIterator(true) 105 | } 106 | } 107 | 108 | fun suspendingIterator( 109 | context: CoroutineContext = EmptyCoroutineContext, 110 | block: suspend SuspendingSequenceBuilder.() -> Unit 111 | ): SuspendingIterator = 112 | SuspendingIteratorCoroutine(context).apply { 113 | nextStep = block.createCoroutine(receiver = this, completion = this) 114 | } 115 | 116 | fun suspendingSequence( 117 | context: CoroutineContext = EmptyCoroutineContext, 118 | block: suspend SuspendingSequenceBuilder.() -> Unit 119 | ): SuspendingSequence = object : SuspendingSequence { 120 | override fun iterator(): SuspendingIterator = suspendingIterator(context, block) 121 | } 122 | 123 | 124 | fun main(args: Array) = runBlocking { 125 | 126 | val dd = suspendingSequence { 127 | (0 until 10) 128 | .map { async { Baker().bake() } } 129 | .forEach { yield(it.await()) } 130 | } 131 | 132 | println("Number of cakes: ${dd.iterator().toList().size}") 133 | } 134 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # Mastering High Performance with Kotlin 5 | 6 | Mastering High Performance with Kotlin 7 | 8 | This is the code repository for [Mastering High Performance with Kotlin](https://www.packtpub.com/application-development/mastering-high-performance-kotlin?utm_source=github&utm_medium=repository&utm_campaign=9781788996648), published by Packt. 9 | 10 | **Find out how to write Kotlin code without overhead and how to use different profiling tools and bytecode viewer to inspect expressions of Kotlin language.** 11 | 12 | ## What is this book about? 13 | The ease with which we write applications has been increasing, but with it comes the need to address their performance. A balancing act between easily implementing complex applications and keeping their performance optimal is a present-day requirement In this book, we explore how to achieve this crucial balance, while developing and deploying applications with Kotlin. 14 | 15 | This book covers the following exciting features: 16 | * Understand the importance of high performance 17 | * Learn performance metrics 18 | * Learn popular design patterns currently being used in Kotlin 19 | * Understand how to apply modern Kotlin features to data processing 20 | * Learn how to use profling tools 21 | 22 | 23 | If you feel this book is for you, get your [copy](https://www.amazon.com/dp/178899664X) today! 24 | 25 | https://www.packtpub.com/ 27 | 28 | ## Instructions and Navigations 29 | All of the code is organized into folders. For example, Chapter02. 30 | To run examples from this book, you will need a computer running Windows, Linux, or Mac OS. You also need IntelliJ IDEA (Ultimate edition version is preferable) and Android Studio. You need basic knowledge of GitHub and Git to clone a project with examples. Since Kotlin is an official language for Android development, Android Studio supports this language out of the box. 31 | 32 | To build the project [import it as Maven project in Intellij IDEA](https://www.jetbrains.com/help/idea/maven-support.html). 33 | 34 | Project contains packages for each chapter that is splitted by sections: 35 | 36 | 37 | 38 | Most of the examples contain a ```main``` function that can run by clicking the ![](https://www.jetbrains.com/help/img/idea/2018.1/run.png) icon in the left gutter and choose the Run or Debug command. 39 | 40 | Project also contains benchmarks that can be run using the following commands: 41 | 1) Build a ```.jar``` file using this command at the root of the repository: ```mvn clean install``` 42 | 2) To run the ```.jar``` with fast benchmarking: ```java -jar target/benchmarks.jar -wi 0 -i 1 -f 1 -tu ns -bm avgt``` 43 | To run the ```.jar``` with default benchmarking: ```java -jar target/benchmarks.jar``` 44 | 45 | 46 | The code will look like the following: 47 | ``` 48 | public inline fun measureTimeMillis(block: () -> Unit) : Long { 49 | val start = System.currentTimeMillis() 50 | block() 51 | return System.currentTimeMillis() - start 52 | } 53 | ``` 54 | 55 | **Following is what you need for this book:** 56 | This book is for Kotlin developers who would like to build reliable and high-performance applications. Prior Kotlin programming knowledge is assumed. 57 | 58 | With the following software and hardware list you can run all code files present in the book (Chapter 1-10). 59 | ### Software and Hardware List 60 | | Chapter | Software required | OS required | 61 | | -------- | ------------------------------------| -----------------------------------| 62 | | 1-10 | IntelliJ IDEA (Ultimate edition) | Windows, Mac OS X, and Linux (Any) | 63 | 64 | We also provide a PDF file that has color images of the screenshots/diagrams used in this book. [Click here to download it](https://www.packtpub.com/sites/default/files/downloads/MasteringHighPerformancewithKotlin_ColorImages.pdf). 65 | 66 | ### Related products 67 | * Hands-On Microservices with Kotlin [[Packt]](https://www.packtpub.com/web-development/microservices-kotlin?utm_source=github&utm_medium=repository&utm_campaign=9781788471459) [[Amazon]](https://www.amazon.com/dp/1788471458) 68 | 69 | * Functional Kotlin [[Packt]](https://www.packtpub.com/application-development/functional-kotlin?utm_source=github&utm_medium=repository&utm_campaign=9781788476485) [[Amazon]](https://www.amazon.com/dp/1788476484) 70 | 71 | ## Get to Know the Author 72 | **Igor Kucherenko** 73 | is an Android developer at Techery, a software development company that uses Kotlin as the main language for Android development. Currently, he lives in Ukraine, where he is a speaker in the Kotlin Dnipro Community, which promotes Kotlin and shares knowledge with audiences at meetups. You can find his articles about Kotlin and Android development on Medium and a blog for Yalantis, where he worked previously. 74 | 75 | ### Suggestions and Feedback 76 | [Click here](https://docs.google.com/forms/d/e/1FAIpQLSdy7dATC6QmEL81FIUuymZ0Wy9vH1jHkvpY57OiMeKGqib_Ow/viewform) if you have any feedback or suggestions. 77 | ### Download a free PDF 78 | 79 | If you have already purchased a print or Kindle version of this book, you can get a DRM-free PDF version at no cost.
Simply click on the link to claim your free PDF.
80 |

https://packt.link/free-ebook/9781788996648

-------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | mastering.kotlin.performance 7 | MasteringHighPerformanceWithKotlin 8 | 1.0 9 | jar 10 | 11 | Mastering High Performance with Kotlin 12 | 13 | 14 | 1.2.41 15 | UTF-8 16 | 1.12 17 | default 18 | 19 | 1.8 20 | benchmarks 21 | 22 | 23 | 28 | 29 | 30 | 31 | sonatype-oss 32 | Sonatype OSS 33 | http://oss.sonatype.org/content/repositories/snapshots 34 | 35 | true 36 | 37 | 38 | 39 | central 40 | http://jcenter.bintray.com 41 | 42 | 43 | 44 | 45 | 46 | sonatype.oss.snapshots 47 | Sonatype OSS Snapshot Repository 48 | http://oss.sonatype.org/content/repositories/snapshots 49 | 50 | false 51 | 52 | 53 | true 54 | 55 | 56 | 57 | 58 | 59 | 60 | org.openjdk.jmh 61 | jmh-core 62 | ${jmh.version} 63 | 64 | 68 | 69 | org.jetbrains.kotlin 70 | kotlin-stdlib 71 | ${kotlin.version} 72 | 73 | 74 | 75 | io.reactivex.rxjava2 76 | rxkotlin 77 | 2.2.0 78 | 79 | 80 | 81 | io.reactivex.rxjava2 82 | rxjava 83 | 2.1.12 84 | 85 | 86 | 87 | org.jetbrains.kotlinx 88 | kotlinx-coroutines-core 89 | 0.21 90 | 91 | 92 | 93 | org.jetbrains.kotlinx 94 | kotlinx-coroutines-rx2 95 | 0.21 96 | 97 | 98 | 99 | 100 | 101 | 3.0.4 102 | 103 | 104 | 105 | 106 | 107 | 110 | 111 | 112 | kotlin-maven-plugin 113 | org.jetbrains.kotlin 114 | 115 | ${kotlin.version} 116 | 117 | 118 | 119 | -Xcoroutines=enable 120 | 121 | 122 | 123 | 124 | 125 | process-sources 126 | generate-sources 127 | 128 | compile 129 | 130 | 131 | 132 | ${project.basedir}/src 133 | 134 | 135 | 136 | 137 | 138 | 139 | 142 | 143 | 144 | org.codehaus.mojo 145 | exec-maven-plugin 146 | 1.2.1 147 | 148 | 149 | generate-resources 150 | 151 | java 152 | 153 | 154 | true 155 | org.openjdk.jmh.generators.bytecode.JmhBytecodeGenerator 156 | 157 | ${project.basedir}/target/classes/ 158 | ${project.basedir}/target/generated-sources/jmh/ 159 | ${project.basedir}/target/classes/ 160 | ${jmh.generator} 161 | 162 | 163 | 164 | 165 | 166 | 167 | org.openjdk.jmh 168 | jmh-generator-bytecode 169 | ${jmh.version} 170 | 171 | 172 | 173 | 174 | 177 | 178 | 179 | org.codehaus.mojo 180 | build-helper-maven-plugin 181 | 1.8 182 | 183 | 184 | add-source 185 | process-resources 186 | 187 | add-source 188 | 189 | 190 | 191 | ${project.basedir}/target/generated-sources/jmh 192 | 193 | 194 | 195 | 196 | 197 | 198 | 201 | 202 | 203 | org.apache.maven.plugins 204 | maven-compiler-plugin 205 | 3.1 206 | 207 | ${javac.target} 208 | ${javac.target} 209 | ${javac.target} 210 | -proc:none 211 | 212 | 213 | 214 | compile-sources 215 | process-sources 216 | 217 | compile 218 | 219 | 220 | 221 | compile-all 222 | compile 223 | 224 | compile 225 | 226 | 227 | 228 | 229 | 230 | 233 | 234 | 235 | org.apache.maven.plugins 236 | maven-shade-plugin 237 | 2.2 238 | 239 | 240 | package 241 | 242 | shade 243 | 244 | 245 | ${uberjar.name} 246 | 247 | 249 | org.openjdk.jmh.Main 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | -------------------------------------------------------------------------------- /target/classes/mastering/kotlin/performance/chapter1/.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 72 | 73 | 74 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 151 | 152 | 153 | 154 | 159 | 160 | 161 | 173 | 174 | 175 | 176 | 190 | 191 | 192 | 193 | 194 | 195 | 199 | 200 | 206 | 207 | 208 | 209 | 227 | 233 | 234 | 235 | 237 | 238 | 239 | 240 | 1527836916601 241 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 281 | 282 | 283 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 509 | 510 | 511 | 512 | 513 | 514 | --------------------------------------------------------------------------------