Конкатенация строк очень медленная, когда ввод большой - PullRequest
3 голосов
/ 08 октября 2009

Такие вещи, как приведенный ниже код, очень медленные:

var str:String = ""
for (var i:Number = 0 ; i<1000000000000000000 ; ++i) {
    str += "someLongLongLongLongLongLongLongLongLongString";
}

В Java есть StringBuilder, но, похоже, нет аналога для AS. Итак, как вы, ребята, справляетесь с конкатенацией больших строк?


Обновление:

Спасибо за ответ всем!

Я только что написал свою собственную программу тестирования . Использование += уже является самым быстрым ... Что медленного, так это поместить его в TextArea ...

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

Ответы [ 5 ]

6 голосов
/ 08 октября 2009

Да, будет медленным, даже с StringBuilder. У меня вопрос: почему вы пытаетесь создать строку размером 46 эксабайт?

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

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

5 голосов
/ 08 октября 2009

Не могу сказать, что у меня есть опыт работы с ActionScript, но для ECMAScript в целом я обнаружил, что массивы могут помочь ускорить конкатенацию строк (пример JavaScript приведен ниже):

var sb = [];
for (var i = 0; i < 10000000000; i++) {
    sb.push('longlonglong');
    // In this particular case you can avoid a method call by doing:
    //sb[i] = 'longlonglong';
}
var str = sb.join('');
2 голосов
/ 08 октября 2009

здесь вы используете злоупотребление типом ...: D ... на AVM2 строки предназначены для представления текста ... они всегда в кодировке Unicode, поэтому им требуется более 2 байтов на символ ... не подходят для хранения последовательности ascii размера i-will-make-your-heap-explode ... если вы действительно хотите манипулировать sh * tload данных, тогда переходите к flash.utils::ByteArray ... не то чтобы это быстрее, но это семантически более правильно и имеет меньший объем памяти ... плюс у него есть собственные методы сжатия, что я очень рекомендую в вашем случае ...: P

2 голосов
/ 08 октября 2009
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
performancetests.Strings (1 iterations)                                 
Player version: MAC 10,0,32,18 (debug)
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
method...................................................ttl ms...avg ms
stringsWithConcatMethod                                   17555 17555.00
stringsWithPlusConcat                                      4972  4972.00
––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

Я не мазохист, поэтому я использовал итерационный цикл 10000000 для этого:

var str:String = ""
for (var i:Number = 0 ; i<10000000 ; ++i) {
    str += "someLongLongLongLongLongLongLongLongLongString";
}

против

var str:String = ""
for (var i:Number = 0 ; i<10000000 ; ++i) {
    str = str.concat("someLongLongLongLongLongLongLongLongLongString");
}

Использование Испытательный комплект Grant Skinner AS3 Performance Test * . Метод String :: concat еще медленнее, хотя, учитывая ваши условия, as3, скорее всего, будет sloooow. (1 итерация в результате - 1 раз прохождение 10000000 итерационных циклов). Я был довольно удивлен результатом. Я думал, что Конкат будет быстрее.

2 голосов
/ 08 октября 2009

Две вещи обычно делают такие операции медленными:

  • Строка растет из памяти, выделенной для нее, поэтому она должна быть перераспределена. Это включает в себя менеджер памяти кучи и копирование содержимого. По мере роста содержимого это означает, что оно много копируется и что система памяти должна работать довольно усердно.
  • Если строка не хранится таким образом, что это означает, что ее длина доступна как операция O (1), конкатенация сначала должна пройти по всей строке, чтобы найти длину, т.е. с чего начать конкатенацию. Означает, что каждая отдельная конкатенация занимает время, пропорциональное длине целевой строки.

Я уверен, что по крайней мере один из них поражает вас (последний может и не быть, не уверен, как строки представляются внутри в ActionScript).

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