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.

Поговорим про performance-тестирование

95 views

Published on

Конференция DotNext 2017 Moscow
2017-11-12

Published in: Engineering
  • Be the first to comment

  • Be the first to like this

Поговорим про performance-тестирование

  1. 1. Поговорим про performance-тестирование Андрей Акиньшин, JetBrains DotNext 2017 Moscow 1/52
  2. 2. О чём будем разговаривать Мы хотим: 2/52
  3. 3. О чём будем разговаривать Мы хотим: 1 Не допустить performance-деградаций 2/52
  4. 4. О чём будем разговаривать Мы хотим: 1 Не допустить performance-деградаций 2 Если допустили, то вовремя об этом узнать 2/52
  5. 5. О чём будем разговаривать Мы хотим: 1 Не допустить performance-деградаций 2 Если допустили, то вовремя об этом узнать 3 Снизить количество ошибок первого рода (Проблемы нет, а мы думаем, что есть) 2/52
  6. 6. О чём будем разговаривать Мы хотим: 1 Не допустить performance-деградаций 2 Если допустили, то вовремя об этом узнать 3 Снизить количество ошибок первого рода (Проблемы нет, а мы думаем, что есть) 4 Снизить количество ошибок второго рода (Проблема есть, а мы думаем, что нет) 2/52
  7. 7. О чём будем разговаривать Мы хотим: 1 Не допустить performance-деградаций 2 Если допустили, то вовремя об этом узнать 3 Снизить количество ошибок первого рода (Проблемы нет, а мы думаем, что есть) 4 Снизить количество ошибок второго рода (Проблема есть, а мы думаем, что нет) 5 Автоматизировать всё, что можно 2/52
  8. 8. Источник для вдохновения 3/52
  9. 9. Источник для вдохновения Rider • Файлов: 200’000+ • Строчек кода: 20’000’000+ • Тестов: 100’000+ • Зависимости: IntelliJ IDEA + ReSharper • Рантаймы внутри: JVM, .NET Framework/Mono • Целевые ОС: Windows, Linux, macOS 4/52
  10. 10. Источник для вдохновения Rider • Файлов: 200’000+ • Строчек кода: 20’000’000+ • Тестов: 100’000+ • Зависимости: IntelliJ IDEA + ReSharper • Рантаймы внутри: JVM, .NET Framework/Mono • Целевые ОС: Windows, Linux, macOS Хочется, чтобы Rider работал очень быстро... 4/52
  11. 11. Заметка 1 Источники performance-данных 5/52 1. Источники performance-данных
  12. 12. Источники performance-данных: крупно «Специальные» performance-тесты 6/52 1. Источники performance-данных
  13. 13. Источники performance-данных: крупно «Специальные» performance-тесты • Микробенчмарки 6/52 1. Источники performance-данных
  14. 14. Источники performance-данных: крупно «Специальные» performance-тесты • Микробенчмарки • Холодный и горячий старт 6/52 1. Источники performance-данных
  15. 15. Источники performance-данных: крупно «Специальные» performance-тесты • Микробенчмарки • Холодный и горячий старт • Performance-тесты на GUI 6/52 1. Источники performance-данных
  16. 16. Источники performance-данных: крупно «Специальные» performance-тесты • Микробенчмарки • Холодный и горячий старт • Performance-тесты на GUI • Нагрузочное тестирование (Яндекс.Танк, JMeter и т.д.) 6/52 1. Источники performance-данных
  17. 17. Источники performance-данных: крупно «Специальные» performance-тесты • Микробенчмарки • Холодный и горячий старт • Performance-тесты на GUI • Нагрузочное тестирование (Яндекс.Танк, JMeter и т.д.) • Автоматизированный поиск точек отказа (capacity planning) 6/52 1. Источники performance-данных
  18. 18. Источники performance-данных: крупно «Специальные» performance-тесты • Микробенчмарки • Холодный и горячий старт • Performance-тесты на GUI • Нагрузочное тестирование (Яндекс.Танк, JMeter и т.д.) • Автоматизированный поиск точек отказа (capacity planning) • Тестирование асимптотики 6/52 1. Источники performance-данных
  19. 19. Источники performance-данных: крупно «Специальные» performance-тесты • Микробенчмарки • Холодный и горячий старт • Performance-тесты на GUI • Нагрузочное тестирование (Яндекс.Танк, JMeter и т.д.) • Автоматизированный поиск точек отказа (capacity planning) • Тестирование асимптотики • ... 6/52 1. Источники performance-данных
  20. 20. Источники performance-данных: крупно «Специальные» performance-тесты • Микробенчмарки • Холодный и горячий старт • Performance-тесты на GUI • Нагрузочное тестирование (Яндекс.Танк, JMeter и т.д.) • Автоматизированный поиск точек отказа (capacity planning) • Тестирование асимптотики • ... «Обычные» тесты • Все тесты, которые у вас уже есть (>10ms) 6/52 1. Источники performance-данных
  21. 21. Обычные тесты vs. Специальные тесты Обычные тесты Специальные тесты 7/52 1. Источники performance-данных
  22. 22. Обычные тесты vs. Специальные тесты Обычные тесты Специальные тесты Случайные машины Выделенные машины 7/52 1. Источники performance-данных
  23. 23. Обычные тесты vs. Специальные тесты Обычные тесты Специальные тесты Случайные машины Выделенные машины Виртуальное окружение Реальное железо 7/52 1. Источники performance-данных
  24. 24. Обычные тесты vs. Специальные тесты Обычные тесты Специальные тесты Случайные машины Выделенные машины Виртуальное окружение Реальное железо Легко писать Сложно писать 7/52 1. Источники performance-данных
  25. 25. Обычные тесты vs. Специальные тесты Обычные тесты Специальные тесты Случайные машины Выделенные машины Виртуальное окружение Реальное железо Легко писать Сложно писать Много и бесплатно Мало и дорого 7/52 1. Источники performance-данных
  26. 26. Метрики Много данных не бывает! Можно собирать и анализировать: • Время прохождения теста • Время прохождения отдельных частей теста • Железные данные: CPU, Memory, Disk, Network, . . . • Характеристики рантайма (например, GC.CollectionCount) • По каждой метрике смотрим на: Min/Max/Mean/Median/Q1/Q3/Percentiles/Distribution 8/52 1. Источники performance-данных
  27. 27. Метрики Много данных не бывает! Можно собирать и анализировать: • Время прохождения теста • Время прохождения отдельных частей теста • Железные данные: CPU, Memory, Disk, Network, . . . • Характеристики рантайма (например, GC.CollectionCount) • По каждой метрике смотрим на: Min/Max/Mean/Median/Q1/Q3/Percentiles/Distribution Не забываем про проблему множественных сравнений . . . 8/52 1. Источники performance-данных
  28. 28. Заметка 2 История 9/52 2. История
  29. 29. Поучительная история Однажды, после перехода с Mono 4.9 на Mono 5.2 наши perf-тесты стали падать . . . 10/52 2. История
  30. 30. Поучительная история Однажды, после перехода с Mono 4.9 на Mono 5.2 наши perf-тесты стали падать . . . private readonly IList<object> array = new string[0]; [Benchmark] public int CountProblem() => array.Count; 10/52 2. История
  31. 31. Поучительная история Однажды, после перехода с Mono 4.9 на Mono 5.2 наши perf-тесты стали падать . . . private readonly IList<object> array = new string[0]; [Benchmark] public int CountProblem() => array.Count; Linux macOS Mono 4.9 ≈5ns ≈5ns Mono 5.2 ≈1400ns ≈2600ns 10/52 2. История
  32. 32. Заметка 3 Оборона против performance-деградаций 11/52 3. Оборона против performance-деградаций
  33. 33. Виды обороны 12/52 3. Оборона против performance-деградаций
  34. 34. Виды обороны • Merge robot Проверяем производительность на каждый мердж 12/52 3. Оборона против performance-деградаций
  35. 35. Виды обороны • Merge robot Проверяем производительность на каждый мердж • Daily tests Запускаем тесты каждый день 12/52 3. Оборона против performance-деградаций
  36. 36. Виды обороны • Merge robot Проверяем производительность на каждый мердж • Daily tests Запускаем тесты каждый день • Retrospective Анализируем исторические данные 12/52 3. Оборона против performance-деградаций
  37. 37. Виды обороны • Merge robot Проверяем производительность на каждый мердж • Daily tests Запускаем тесты каждый день • Retrospective Анализируем исторические данные • Check points Проверяем опасные изменения 12/52 3. Оборона против performance-деградаций
  38. 38. Виды обороны • Merge robot Проверяем производительность на каждый мердж • Daily tests Запускаем тесты каждый день • Retrospective Анализируем исторические данные • Check points Проверяем опасные изменения • Pre-release Проверяем регрессию перед самым релизом 12/52 3. Оборона против performance-деградаций
  39. 39. Сравнение видов обороны Обнаружение Точность Процесс 13/52 3. Оборона против performance-деградаций
  40. 40. Сравнение видов обороны Обнаружение Точность Процесс Merge robot Вовремя Средняя Автоматический 13/52 3. Оборона против performance-деградаций
  41. 41. Сравнение видов обороны Обнаружение Точность Процесс Merge robot Вовремя Средняя Автоматический Daily tests Поздно Хорошая Полуручной Retrospective Слишком поздно Отличная Полуручной 13/52 3. Оборона против performance-деградаций
  42. 42. Сравнение видов обороны Обнаружение Точность Процесс Merge robot Вовремя Средняя Автоматический Daily tests Поздно Хорошая Полуручной Retrospective Слишком поздно Отличная Полуручной Check points Вовремя Отличная Ручной Pre-release Зависит Отличная Ручной 13/52 3. Оборона против performance-деградаций
  43. 43. Сравнение видов обороны Обнаружение Точность Процесс Merge robot Вовремя Средняя Автоматический Daily tests Поздно Хорошая Полуручной Retrospective Слишком поздно Отличная Полуручной Check points Вовремя Отличная Ручной Pre-release Зависит Отличная Ручной И ещё несколько важных факторов: • Время прогона • Количество билд-агентов и их стоимость • Спектр проблем, которые можно обнаружить 13/52 3. Оборона против performance-деградаций
  44. 44. Заметка 4 Когда бить тревогу? 14/52 4. Когда бить тревогу?
  45. 45. Alarm-критерии Ручной • Специальный программист, который мониторит тесты 24/7 15/52 4. Когда бить тревогу?
  46. 46. Alarm-критерии Автоматизированный • Абсолютный timeout • Относительный timeout • Исторические данные и статистика 16/52 4. Когда бить тревогу?
  47. 47. Alarm-критерии Полуавтоматизированный • Система, которая формирует список performance-проблем • Специальный программист, который разбирает этот список 17/52 4. Когда бить тревогу?
  48. 48. Заметка 5 Performance-аномалии 18/52 5. Performance-аномалии
  49. 49. Охота за performance-аномалиями 19/52 5. Performance-аномалии
  50. 50. Охота за performance-аномалиями • Performance-пространство — множество всех performance-метрик тестов на всевозможных конфигурациях. 19/52 5. Performance-аномалии
  51. 51. Охота за performance-аномалиями • Performance-пространство — множество всех performance-метрик тестов на всевозможных конфигурациях. • Performance-аномалия — ситуация, при которой performance-пространство выглядит странно. 19/52 5. Performance-аномалии
  52. 52. Охота за performance-аномалиями • Performance-пространство — множество всех performance-метрик тестов на всевозможных конфигурациях. • Performance-аномалия — ситуация, при которой performance-пространство выглядит странно. • Performance-чистота — отсутствие performance-аномалий 19/52 5. Performance-аномалии
  53. 53. Наведение performance-чистоты позволяет 20/52 5. Performance-аномалии
  54. 54. Наведение performance-чистоты позволяет • Находить проблемы, на которые не стоят assert’ы 20/52 5. Performance-аномалии
  55. 55. Наведение performance-чистоты позволяет • Находить проблемы, на которые не стоят assert’ы • Ускорять билд 20/52 5. Performance-аномалии
  56. 56. Наведение performance-чистоты позволяет • Находить проблемы, на которые не стоят assert’ы • Ускорять билд • Находить flaky-тесты 20/52 5. Performance-аномалии
  57. 57. Наведение performance-чистоты позволяет • Находить проблемы, на которые не стоят assert’ы • Ускорять билд • Находить flaky-тесты • Уменьшать количество тестов, которые в будущем помешают найти действительно критичные проблемы 20/52 5. Performance-аномалии
  58. 58. Заметка 6 Кластеризация 21/52 6. Кластеризация
  59. 59. Какая OS самая быстрая? 22/52 6. Кластеризация
  60. 60. Какая OS самая быстрая? 23/52 6. Кластеризация
  61. 61. Какая OS самая быстрая? 24/52 6. Кластеризация
  62. 62. Заметка 7 Деградации: большие и маленькие 25/52 7. Деградации: большие и маленькие
  63. 63. Большая деградация 26/52 7. Деградации: большие и маленькие
  64. 64. Маленькие деградации 27/52 7. Деградации: большие и маленькие
  65. 65. Распределение 28/52 7. Деградации: большие и маленькие
  66. 66. Внезапные улучшения 29/52 7. Деградации: большие и маленькие
  67. 67. Заметка 8 Распределения странной формы 30/52 8. Распределения странной формы
  68. 68. Плохой код while (!isReady) { Thread.Sleep(100); // Update state } 31/52 8. Распределения странной формы
  69. 69. Плохой код while (!isReady) { Thread.Sleep(100); // Update state } Thread.Sleep — источник постоянных проблем 31/52 8. Распределения странной формы
  70. 70. Мультимодальное распределение 32/52 8. Распределения странной формы
  71. 71. Бимодальное распределение 33/52 8. Распределения странной формы
  72. 72. Заглядываем внутрь // OutputLineSplitterTest_testFlushing while (!isFinished.get()) { mySplitter.process(StringUtil.repeat("A", 100), each); i++; if (i % 10 == 0) { written.release(); try { if (!read.tryAcquire(10, TimeUnit.SECONDS)) throw new TimeoutException(); } catch (Exception e) { throw new RuntimeException(e); } } } 34/52 8. Распределения странной формы
  73. 73. Просто странное распределение По мотивам экспериментов с .NET Core 35/52 8. Распределения странной формы
  74. 74. Заметка 9 Большая дисперсия 36/52 9. Большая дисперсия
  75. 75. Очень большая дисперсия 37/52 9. Большая дисперсия
  76. 76. Подозрительная дисперсия 38/52 9. Большая дисперсия
  77. 77. Смотрим тест [Test] public void TestFullTrigrams() { const int start = 256; const int limit = 512; for (var a = start; a <= limit; ++a) for (var b = start; b <= limit; ++b) for (var c = start; c <= limit; ++c) TestTrigramToken((char)a, (char)b, (char)c); } 39/52 9. Большая дисперсия
  78. 78. Смотрим тест private static void TestTrigramToken(char a, char b, char c) { var testedTrigram = new TrigramToken(a, b, c); var testedTrigramHash = (int)testedTrigram; var expectedIsShort = ((a | b | c) >> 8 == 0); Assert.AreEqual(expectedIsShort, testedTrigram.IsShort()); Assert.AreEqual(c, TrigramToken.ExtractLastCharacter(testedTrigramHash)); } 40/52 9. Большая дисперсия
  79. 79. Смотрим снэпшот 41/52 9. Большая дисперсия
  80. 80. Смотрим исходники // NUnit 2.6.4 public static void AreEqual(int expected, int actual) { Assert.That(actual, Is.EqualTo(expected), null, null); } public static void AreEqual(object expected, object actual) { Assert.That(actual, Is.EqualTo(expected), null, null); } public static EqualConstraint EqualTo(object expected) { return new EqualConstraint(expected); } 42/52 9. Большая дисперсия
  81. 81. Заметка 10 Когда аномалия есть, а проблемы нету 43/52 10. Когда аномалия есть, а проблемы нету
  82. 82. Ложные друзья performance-инженера 44/52 10. Когда аномалия есть, а проблемы нету
  83. 83. Ложные друзья performance-инженера • Изменения в тесте или порядке тестов 44/52 10. Когда аномалия есть, а проблемы нету
  84. 84. Ложные друзья performance-инженера • Изменения в тесте или порядке тестов • Изменения в агенте или окружении 44/52 10. Когда аномалия есть, а проблемы нету
  85. 85. Ложные друзья performance-инженера • Изменения в тесте или порядке тестов • Изменения в агенте или окружении • Изменения в tradeoff-ах 44/52 10. Когда аномалия есть, а проблемы нету
  86. 86. Ложные друзья performance-инженера • Изменения в тесте или порядке тестов • Изменения в агенте или окружении • Изменения в tradeoff-ах • Да и вообще, любые изменения 44/52 10. Когда аномалия есть, а проблемы нету
  87. 87. Найди деградацию! 45/52 10. Когда аномалия есть, а проблемы нету
  88. 88. Найди деградацию! А её нету, просто macOS-агентам было плохо. . . 45/52 10. Когда аномалия есть, а проблемы нету
  89. 89. Заметка 11 Performance Driven Development (PDD) 46/52 11. Performance Driven Development (PDD)
  90. 90. Performance Driven Development (PDD) 47/52 11. Performance Driven Development (PDD)
  91. 91. Performance Driven Development (PDD) 1 Пишем тест 47/52 11. Performance Driven Development (PDD)
  92. 92. Performance Driven Development (PDD) 1 Пишем тест 2 Собираем performance-метрики и задаём performance-требования 47/52 11. Performance Driven Development (PDD)
  93. 93. Performance Driven Development (PDD) 1 Пишем тест 2 Собираем performance-метрики и задаём performance-требования 3 Проверяем, что тест красный 47/52 11. Performance Driven Development (PDD)
  94. 94. Performance Driven Development (PDD) 1 Пишем тест 2 Собираем performance-метрики и задаём performance-требования 3 Проверяем, что тест красный 4 Делаем рефакторинг и оптимизации 47/52 11. Performance Driven Development (PDD)
  95. 95. Performance Driven Development (PDD) 1 Пишем тест 2 Собираем performance-метрики и задаём performance-требования 3 Проверяем, что тест красный 4 Делаем рефакторинг и оптимизации 5 Проверяем, что тест зелёный (И все остальные тесты тоже) 47/52 11. Performance Driven Development (PDD)
  96. 96. Performance Driven Development (PDD) 1 Пишем тест 2 Собираем performance-метрики и задаём performance-требования 3 Проверяем, что тест красный 4 Делаем рефакторинг и оптимизации 5 Проверяем, что тест зелёный (И все остальные тесты тоже) 6 Возвращаемся к шагу 1 47/52 11. Performance Driven Development (PDD)
  97. 97. Заметка 12 Performance Culture 48/52 12. Performance Culture
  98. 98. Performance Culture 49/52 12. Performance Culture
  99. 99. Заметка 13 Заключительные мысли 50/52 13. Заключительные мысли
  100. 100. Мораль 51/52 13. Заключительные мысли
  101. 101. Мораль • Performance-тестирование — увлекательно и полезно, но сложно. 51/52 13. Заключительные мысли
  102. 102. Мораль • Performance-тестирование — увлекательно и полезно, но сложно. • Тестировать performance можно и нужно. 51/52 13. Заключительные мысли
  103. 103. Мораль • Performance-тестирование — увлекательно и полезно, но сложно. • Тестировать performance можно и нужно. • Соблюдайте performance-чистоту! 51/52 13. Заключительные мысли
  104. 104. Мораль • Performance-тестирование — увлекательно и полезно, но сложно. • Тестировать performance можно и нужно. • Соблюдайте performance-чистоту! • Будьте performance-культурными! 51/52 13. Заключительные мысли
  105. 105. Вопросы? Андрей Акиньшин http://aakinshin.net https://github.com/AndreyAkinshin https://twitter.com/andrey_akinshin andrey.akinshin@gmail.com 52/52 13. Заключительные мысли

×