Android / Java конвертирует из int в строку без выделения? - PullRequest
3 голосов
/ 04 июля 2011

задумался о необходимости многократного преобразования из int в String в течение одного из приложений, которые я создаю для Android.Я сел и написал небольшой служебный класс, который, я думаю, облегчит выделение скрывающихся переменных, которые вы не можете увидеть из-за вызовов функций, таких как Integer.toString () и т. Д.

private int[] iMods = {
        1,
        10,
        100,
        1000,
        10000,
        100000,
        1000000,
        10000000,
        100000000,
        1000000000};

private int tmpInt = 0;
private int MAX_DIGITS = 6;
private char[] cScoreDigit = new char[MAX_DIGITS];
private int[] iScoreDigit = new int[MAX_DIGITS];
private StringBuilder mScoreStringBuilder = new StringBuilder("000000");


public String intToString(final int pInt, final int pMAX_DIGITS){
    MAX_DIGITS = pMAX_DIGITS;

    for (tmpInt = 1; tmpInt <= MAX_DIGITS; tmpInt++){   // Set each cScoreDigit to proper equivalent of iScoreDigit without cast!
        switch ((pInt % iMods[tmpInt]) / iMods[tmpInt - 1]){
        case 0:
            cScoreDigit[MAX_DIGITS - tmpInt] = '0';
            break;
        case 1:
            cScoreDigit[MAX_DIGITS - tmpInt] = '1';
            break;
        case 2:
            cScoreDigit[MAX_DIGITS - tmpInt] = '2';
            break;
        case 3:
            cScoreDigit[MAX_DIGITS - tmpInt] = '3';
            break;
        case 4:
            cScoreDigit[MAX_DIGITS - tmpInt] = '4';
            break;
        case 5:
            cScoreDigit[MAX_DIGITS - tmpInt] = '5';
            break;
        case 6:
            cScoreDigit[MAX_DIGITS - tmpInt] = '6';
            break;
        case 7:
            cScoreDigit[MAX_DIGITS - tmpInt] = '7';
            break;
        case 8:
            cScoreDigit[MAX_DIGITS - tmpInt] = '8';
            break;
        case 9:
            cScoreDigit[MAX_DIGITS - tmpInt] = '9';
        }       
    }

    // Delete all 0's
    mScoreStringBuilder.delete(0, mScoreStringBuilder.length());
    return mScoreStringBuilder.append(cScoreDigit).toString();
}

Мне просто любопытно, а) действительно ли это правильный способ сделать что-то подобное, и б) стоит ли что-то подобное изучать из-за дополнительной математики, происходящей на каждом шаге?Кажется контрпродуктивным, но, по крайней мере, помешает GC работать правильно?Заранее спасибо!

[EDIT]

Мне стало известно, что StringBuilder.toString () фактически выделит временный объект, что я и сделалпытаясь избежать.Любой другой способ просто преобразовать из char [] в String без выделения?Или, как указано ниже, это просто невозможно с классом String?

1 Ответ

2 голосов
/ 04 июля 2011

Нет, toString в конце создает новую строку (проверьте код, если хотите, все источники Java-библиотеки доступны).

Поскольку строки неизменяемы, на самом деле нет способа избежать выделения, потому чтовы возвращаете строку.

Если вы вернете компоновщик строк, который вы использовали для создания своего номера, и повторно использовали его при следующем вызове, и НИКОГДА не конвертируете его в строку, все будет в порядке, но в следующий раз вы преобразуете его в строку(независимо от того, как вы это сделали) вы выделяете память.

Чтобы сделать это, ваш метод должен либо принять переданный изменяемый объект (StringBuilder или char массив), либо ему придется повторно использовать статический объект.(делая его однопоточным)

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

Также помните, что в Java кратковременное выделение памяти не так плохо, как вы думаете, - это больше похоже на распределение стека в C с точки зрения производительности.

Исследования и тесты, которые я провел, показали, что единственное, что вы можете сделать, - это избегать объединения строк в цикле - всего остального (включая одноразовую строку conc.Любой простой код будет таким же быстрым или быстрым, как и все, что вы можете придумать.

...