Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Kotlin Perfomance on Android / Александр Смирнов (Splyt)

127 views

Published on

РИТ++ 2017, AppsConf
Зал Касабланка, 6 июня, 14:00

Тезисы:
http://appsconf.ru/2017/abstracts/2816.html

В докладе рассмотрим цену использования Kotlin в Runtime, обсудим варианты, как улучшить картину мира. Смотреть будем с точки зрения производительности, синхронно углубляясь в особенности Android, а также подумаем, как можно использовать получившийся байткод.

В докладе срыв подкапотных оптимизаций, байткод и цифры, которые покажут, насколько сильно вам смогут помочь все указанные оптимизации.

Published in: Engineering
  • Be the first to comment

Kotlin Perfomance on Android / Александр Смирнов (Splyt)

  1. 1. KOTLIN PERFOMANCE ON ANDROID ALEXANDER SMIRNOV 06.06.2017
  2. 2. WHOAMI ANDROID DEVELOPER SINCE 2012 ANDROID В ЛИЦАХ (YOUTUBE – TELEGRAM) WORKING IN SPLYT MOSDROID
  3. 3. QUIZ: KOTLIN VS JAVA!? 1. МЕДЛЕННЕЕ 2. ОДИНАКОВО 3. БЫСТРЕЕ
  4. 4. ВСЁ ПОМЕРЯЕМ fun measure() : Long {
 val startTime = System.nanoTime()
 work()
 return System.nanoTime() - startTime
 } adb shell dumpsys gfxinfo %package_name%
  5. 5. QUIZ: ГДЕ ПЕРФОМАНС ВАЖЕН? 1. ОДНОЗНАЧНО ВЕЗДЕ 2. UITHREAD 3. CUSTOM VIEW + ANIMATIONS
  6. 6. VIEWS && UI THREAD
  7. 7. KOTLIN STYLE COLLECTION API METHOD DEFAULT PARAMETERS DATA CLASSES REIFIED TYPES COROUTINES
  8. 8. class Test {
 
 var a = 5
 var b = 6
 val c = B()
 
 fun work() {
 val d = a + b
 val e = c.a + c.b
 }
 }
 
 class B(@JvmField var a: Int = 5, 
 var b: Int = 6) FIELDS
  9. 9. L0 LINENUMBER 10 L0 ALOAD 0 GETFIELD kotlin/Test.a : I ALOAD 0 GETFIELD kotlin/Test.b : I IADD ISTORE 1 FIELDS var a = 5
 var b = 6
 
 val d = a + b
  10. 10. L1 LINENUMBER 11 L1 ALOAD 0 GETFIELD kotlin/Test.c : Lkotlin/B; GETFIELD kotlin/B.a : I ALOAD 0 GETFIELD kotlin/Test.c : Lkotlin/B; INVOKEVIRTUAL kotlin/B.getB ()I IADD ISTORE 2 FIELDS val e = c.a + c.b
 
 class B(@JvmField var a: Int = 5, 
 var b: Int = 6)
  11. 11. STATIC!? companion object {
 var k = 5
 
 fun work2() : Int = 42
 }
  12. 12. NOT STATIC companion object {
 var k = 5
 
 fun work2() : Int = 42 } val i = k + work2() L2 LINENUMBER 21 L2 GETSTATIC kotlin/Test.Companion : Lkotlin/Test$Companion; INVOKEVIRTUAL kotlin/Test$Companion.getK ()I GETSTATIC kotlin/Test.Companion : Lkotlin/Test$Companion; INVOKEVIRTUAL kotlin/Test$Companion.work2 ()I IADD ISTORE 3
  13. 13. NOT STATIC private static int k = 5;
 public static final Test.Companion Companion = new Test.Companion((DefaultConstructorMarker)null); 
 public static final class Companion {
 public final int getK() { return Test.k;}
 
 public final void setK(int var1) {
 Test.k = var1;
 }
 
 public final int work2() { return 42; }
 
 private Companion() { }
 
 // $FF: synthetic method
 public Companion(DefaultConstructorMarker $constructor_marker) { this(); }
 }
  14. 14. NOT STATIC val i = k + work2() companion object { @JvmField
 var k = 5
 @JvmStatic
 fun work2() : Int = 42 } private static int k = 5;
 public static final Test.Companion Companion = new Test.Companion((DefaultConstructorMarker)null); 
 public static final class Companion {
 @JvmStatic
 public final int work2() { return 42; }
 
 private Companion() {}
 
 // $FF: synthetic method
 public Companion(DefaultConstructorMarker $constructor_marker) { this(); } }
  15. 15. NOT STATIC val i = k + work2() companion object { @JvmField
 var k = 5
 @JvmStatic
 fun work2() : Int = 42 } L2 LINENUMBER 21 L2 GETSTATIC kotlin/Test.k : I GETSTATIC kotlin/Test.Companion : Lkotlin/Test$Companion; INVOKEVIRTUAL kotlin/Test$Companion.work2 ()I IADD ISTORE 3
  16. 16. REAL STATIC !? object A {
 fun test() = 53
 } L3 LINENUMBER 23 L3 GETSTATIC kotlin/A.INSTANCE : Lkotlin/A; INVOKEVIRTUAL kotlin/A.test ()I POP
  17. 17. STATIC! fun test2() = 99 L4 LINENUMBER 24 L4 INVOKESTATIC kotlin/TestKt.test2 ()I POP
  18. 18. NULLABILITY fun test(first: String, second: String?) : String {
 second ?: return first
 
 return "$first $second"
 }
  19. 19. NULLABILITY fun test(first: String, second: String?) : String {
 second ?: return first
 
 return "$first $second"
 } @NotNull
 public final String test(@NotNull String first, @Nullable String second) {
 Intrinsics.checkParameterIsNotNull(first, "first");
 return second != null ? (first + " " + second) : first;
 }
  20. 20. var a = 5
 var b = 6
 var bOption : Int? = 6 PRIMITIVES private int a = 5;
 private int b = 6;
 @Nullable private Integer bOption = Integer.valueOf(6);
  21. 21. AUTOBOXING val a: String? = null
 var b = a?.isBlank() == true
  22. 22. AUTOBOXING val a: String? = null
 var b = a?.isBlank() == true if (a != null && a.isBlank()) true else false
  23. 23. AUTOBOXING val a: String? = null
 var b = a?.isBlank() == true String a = (String)null;
 boolean b = Intrinsics.areEqual(a != null ? Boolean.valueOf(StringsKt.isBlank((CharSequence)a)) : null, Boolean.valueOf(true)); if (a != null && a.isBlank()) true else false
  24. 24. LOOPS list.forEach {
 work(it * 2)
 }
  25. 25. LOOPS inline fun <reified T> List<T>.foreach(crossinline action: (T) -> Unit): Unit {
 val size = size
 var i = 0 
 while (i < size) {
 action(get(i))
 i++
 }
 } list.foreach {
 work(it * 2)
 }
  26. 26. RANGES inline fun <reified T> List<T>.foreach(crossinline action: (T) -> Unit): Unit {
 val size = size 
 for(i in 0..size) {
 work(i * 2)
 } 
 }
  27. 27. INTRINSICS
  28. 28. INTRINSICS class Test {
 
 fun concat(first: String, second: String) = 
 "$first $second"
 
 }
  29. 29. INTRINSICS public final class Test {
 @NotNull
 public final String concat(@NotNull String first,
 @NotNull String second) {
 Intrinsics.checkParameterIsNotNull(first, "first");
 Intrinsics.checkParameterIsNotNull(second, "second");
 return first + " " + second;
 }
 }
  30. 30. INTRINSICS public final class Test {
 @NotNull
 public final String concat(@NotNull String first, 
 @NotNull String second) {
 return first + " " + second;
 }
 } kotlinc -Xno-call-assertions -Xno-param-assertions Test.kt
  31. 31. REDEX ИНЛАЙНИТ, НО НЕ ВСЁ ДЕЛАЕТ ДРУГИЕ ОПТИМИЗАЦИИ – 7% К ВЕСУ APK РЕШЕНИЕ ОТ FACEBOOK
  32. 32. BENCHMARKS PARTICLES DRAWABLE BY YAROSLAV MYTKALYK (DOCTOROR) 4 DIFFERENT PHONES DUMPSYS GFXINFO + MANY BENCHMARKING HTTPS://GITHUB.COM/SMRED
  33. 33. 0 3,75 7,5 11,25 15 Java Kotlin Kotlin+ Min Median Mean BENCHMARKS 1.2 ГГЦ – 1 ГБ ОЗУ 4.4.2 – 480X854 HUAWEI Y54 I-U02
  34. 34. BENCHMARKS 1.2 ГГЦ – 1 ГБ ОЗУ 4.4.2 – 480X854 HUAWEI Y54 I-U02 JAVA KOTLIN KOTLIN+ Min 9,82 9,64 9,24 Median 13,667 13,98 13,58 Mean 14,375 14,875 14,524
  35. 35. BENCHMARKS 1.3 ГГЦ – 1 ГБ ОЗУ
 4.4.2 – 960X540 ONN K7 SUNNY JAVA KOTLIN KOTLIN+ Min 9,73 10,01 9,75 Median 13,31 13,58 13,31 Mean 13,549 13,847 13,625
  36. 36. BENCHMARKS 2.1 ГГЦ + 1.5 ГГЦ – 3 ГБ ОЗУ 
 7.0 – 2560X1440 SAMSUNG GALAXY S6 JAVA KOTLIN KOTLIN+ Min 13,62 13 13,12 Median 24,155 24,675 23,53 Mean 23,924 25,567 23,753
  37. 37. BENCHMARKS 2.15 ГГЦ + 1.6 ГГЦ– 4 ГБ ОЗУ
 7.1.2 – 1920X1080 GOOGLE PIXEL JAVA KOTLIN KOTLIN+ Min 7,56 7,37 7,3 Median 12,96 12,89 12,9 Mean 13,579 13,624 13,553
  38. 38. ИТОГО БЫСТРОДЕЙСТВИЕ ВАЖНО ТОЛЬКО НА UI ПОТОКЕ ОЧЕНЬ КРИТИЧНО ТОЛЬКО В ONMEASURE - ONLAYOUT - ONDRAW ПРАКТИЧЕСКИ ВСЕГДА МОЖНО НАПИСАТЬ С ИДЕНТИЧНОЙ СКОРОСТЬ РАБОТЫ ПРЕЖДЕВРЕМЕННЫЕ ОПТИМИЗАЦИИ ЗЛО
  39. 39. ENJOY alexander.smirnov@splyt.com @_smred @smred

×