Вызывает getResources (). GetString (<string_id>, params) внутри цикла снижает производительность - PullRequest
0 голосов
/ 08 ноября 2018

Я хотел бы знать, ухудшает ли производительность вызов getResources (). GetString (, params) внутри цикла.

У меня есть строка ниже, определенная в strings.xml

<string name="score">The score is %d</string>

и внутри цикла я получаю к нему доступ вот так

textView.setText(getResources().getString(R.string.score, score));

Я не знаю, как getResources().getString() работает внутри, поэтому не уверен, что это хорошая идея - вызывать это в длинном цикле.

Если это тяжелая операция, я мог бы использовать String.format() внутри класса Java, но тогда я потеряю соответствующую локализацию, определенную для этой строки.

Пожалуйста, предложите, если это плохая практика, и есть ли лучший подход.

1 Ответ

0 голосов
/ 08 ноября 2018

Лучший способ ответить на такой вопрос - попробовать его и измерить результаты. Я сделал эти строки:

<string name="plain">Hello world</string>
<string name="variable">Hello %1$s</string>

А потом я сделал приложение, которое загружало каждый из них один раз, а затем каждый из них тысячу раз, и измерило количество наносекунд, которое потребовалось. Я запустил его на довольно старом планшете под управлением довольно старой версии Android и получил следующие результаты:

getString(R.string.plain);
getString(R.string.variable, "StackOverflow");
I/System.out(31427): Loading one plain string took 91,552 nanos
I/System.out(31427): Loading one variable string took 183,106 nanos
I/System.out(31427): Loading a thousand plain strings took 38,055,421 nanos
I/System.out(31427): Loading a thousand plain strings took 67,352,294 nanos

Таким образом, требуется 0,18 миллисекунды, чтобы загрузить строку с аргументами формата один раз, и 67,35 миллисекунды, чтобы сделать то же самое тысячу раз. Мой вывод заключается в том, что загрузка одного и того же ресурса многократно имеет некоторую оптимизацию, но не невероятную сумму (это заняло около одной трети, пока мы ожидали без оптимизации).

Я также измерял тот же тест, используя String.format("Hello %s", "StackOverflow"), и получил следующие результаты:

String.format("Hello %s", "StackOverflow");
I/System.out(31849): Formatting one variable string took 152,588 nanos
I/System.out(31849): Formatting a thousand variable strings took 22,613,526 nanos

Таким образом, выполнение форматирования непосредственно в Java немного быстрее для одной попытки, но значительно быстрее при повторении.

Наконец, тест, который устраняет разрыв. Я использую getString() без аргументов форматирования, а затем String.format() для форматирования. Это означает, что я получаю доступ к структуре ресурсов только один раз, но все же получаю преимущества интернационализации и т. Д. Вот мои результаты

String template = getString(R.string.variable);
String.format(template, "StackOverflow");
I/System.out(32094): Formatting one variable string took 213,623 nanos
I/System.out(32094): Formatting a thousand variable strings took 28,015,135 nanos

Здесь один вызов - худший из всех. Это имеет смысл; мы вручную выполняем всю работу, которую получали раньше «бесплатно». Но делать это тысячу раз - все еще значительный выигрыш при загрузке ресурсов каждый раз.


В общем, вопрос по-прежнему сводится к тому, что вы делаете, как часто вы это делаете, и какую производительность вам нужно. Учтите, что Android рисует кадр на экране примерно каждые 16 миллисекунд ... загрузка тысячи переменных строк из ресурсов заставит вас пропустить 3-4 кадра. Но если вы загружаете только сто строк, вы не пропустите ни одной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...