Я думаю, что происходит, но я ни в коем случае не уверен...
Код, вызывающий вставку запятых, tryMinimizeStringArrayLiteral
в PeeholeSubstituteAlternateSyntax.java.
Этот метод содержит список символов, которые, вероятно, имеют низкое кодирование Хаффмана и поэтому предпочтительны. разделить на чем другие символы. Вы можете увидеть результат этого, если попробуете что-то вроде этого:
"a b c d e f g".split(" "); //Uncompiled, split on spaces
"a,b,c,d,e,f,g".split(","); //Compiled, split on commas (same size)
Компилятор заменит символ, который вы пытаетесь разбить, на тот, который он считает благоприятным. Он делает это, перебирая символы строки и находя наиболее подходящий символ разделения, который не встречается в строке:
// These delimiters are chars that appears a lot in the program therefore
// probably have a small Huffman encoding.
NEXT_DELIMITER: for (char delimiter : new char[]{',', ' ', ';', '{', '}'}) {
for (String cur : strings) {
if (cur.indexOf(delimiter) != -1) {
continue NEXT_DELIMITER;
}
}
String template = Joiner.on(delimiter).join(strings);
//...
}
В приведенном выше фрагменте вы можете увидеть массив символов, который компилятор считает оптимальным для разбиения. Запятая стоит первой (поэтому в моем примере с пространством выше пробелы заменены запятыми).
Я считаю, что вставка запятых в случае, когда строка для разделения является пустой строкой, может быть просто недосмотром. По-видимому, для этого случая не существует какой-либо специальной обработки, поэтому он обрабатывается как любой другой вызов split
, и каждый символ соединяется с первым подходящим символом из массива, показанного в приведенном выше фрагменте.
Еще один пример того, как компилятор работает с методом split
:
"a,;b;c;d;e;f;g".split(";"); //Uncompiled, split on semi-colons
"a, b c d e f g".split(" "); //Compiled, split on spaces
На этот раз, поскольку исходная строка уже содержит запятую (и мы не хотим разбивать символ запятой), запятая не может быть выбрана из массива символов с низким кодированием Хаффмана, поэтому следующим лучшим выбором будет выделено (пробел).
Обновить
После некоторых дальнейших исследований этого, это определенно не ошибка. Такое поведение на самом деле предусмотрено дизайном, и, на мой взгляд, это очень умная маленькая оптимизация, если учесть, что компилятор Closure предпочитает скорость скомпилированного кода размеру.
Выше я пару раз упомянул кодировку Хаффмана. Алгоритм кодирования Хаффмана, объясняемый очень просто, присваивает вес каждому символу, появляющемуся в кодируемом тексте. Вес основан на частоте появления каждого символа. Эти частоты используются для построения бинарного дерева с наиболее распространенным символом в корне. Это означает, что наиболее распространенные символы декодируются быстрее, поскольку они находятся ближе к корню дерева.
И поскольку алгоритм Хаффмана является значительной частью алгоритма DEFLATE, используемого gzip. Поэтому, если ваш веб-сервер настроен на использование gzip, ваши пользователи получат выгоду от этой умной оптимизации.
person
James Allardice
schedule
18.04.2012