Site icon AppTractor

Профилирование вашего I/O

В статьях «Профилирование — это хорошо» и «Конфигурация Gradle — смерть от тысяч порезов бумагой» я говорил о важности каждой миллисекунды на этапе конфигурации Gradle. Сокращение ввода-вывода на этом этапе — еще один важный аспект. В этой заметке я рассказываю, как я наткнулся на ненужные операции ввода-вывода на этапе конфигурации Gradle в AndroidX и исправил их.

Изучая трассировку ./gradlew build —dry-run в случае чистой сборки на холодную, я обнаружил, что в первые 20 секунд на PGPPublicKeyRing тратится удивительно много времени — 2.6 секунды.

AndroidX работает с включенной проверкой подписи Gradle, поэтому не удивительно, что он читает файл, но удивительно, что это занимает так много времени для файла размером 760 Кб с SSD. Увидев, что это событие чтения файла, я перешел на вкладку событий, чтобы посмотреть, что происходит.

Здесь я обнаружил десятки тысяч чтений файла verification-keyrings.keys, каждое из которых состояло из 1 байта. Затем я щелкнул на одной из записей, чтобы посмотреть трассировку стека.

Если посмотреть на это, то это либо ошибка в библиотеке BouncyCastle PGP, либо в Gradle. В SecuritySupport.java:111 мы видим, что createInputStreamFor(keyringFile) используется для создания этого входного потока, отправляемого в библиотеку BouncyCastle.

private static InputStream createInputStreamFor(
   File keyringFile) throws IOException {
      InputStream stream = new FileInputStream(keyringFile);
      if (keyringFile.getName().endsWith(KEYS_FILE_EXT)) {
         return new ArmoredInputStream(stream);
      }
      return stream;
   }

Использование FileInputStream без обертывания его BufferedInputStream приводит к вызову операции ввода-вывода для каждого вызова InputStream#read(). И это была именно ошибка в Gradle! У нас будет исправление для этого в Gradle 8.1.

Используя тот же процесс, я также смог обнаружить, что код AndroidX buildSrc выполнял ввод/вывод на этапе конфигурации, чтобы проверить, есть ли в данном проекте тестовый код, и смог удалить его, сэкономив сотни I/O-вызовов на этом этапе.

Источник

Exit mobile version