Что нового

Конкатенация строк. Как ускорить?

Suppir

Продвинутый
Сообщения
967
Репутация
62
Нужно склеить 10 тысяч строк в одну строку.

Пишу на AutoIt:

Код:
global $x, $line1, $line2 

$line1 = 'Решение городской Думы Краснодара от 23 июня 2011 г. N 14 п. 8 “О внесении изменений в решение городской Думы Краснодара от 28.01.2010 N 69 п. 5 “О дополнительных мерах социальной поддержки отдельных категорий граждан”';

for $x = 1 to 10000
	$line2 = $line2 & @CRLF & $line1
Next
	
filewrite("result_autoit.txt", $line2)


Время работы - 56 сек.


Пишу на Perl (5.14):

Код:
$line1 = 'Решение городской Думы Краснодара от 23 июня 2011 г. N 14 п. 8 “О внесении изменений в решение городской Думы Краснодара от 28.01.2010 N 69 п. 5 “О дополнительных мерах социальной поддержки отдельных категорий граждан”';

for (1 .. 10000){
	$line2 .= "\n$line1";
}

open(OUT, ">result_perl.txt");
print OUT $line2;

Время работы - 0,12 сек.

Результат выдается одинаковый, только на Perl получилось в 466 раз быстрее. Написал ради интереса не 10 тыс., а миллион циклов - получилось 3,5 секунды и файл в 220 Мб. Выходит, что Perl колбасит строки быстрее, чем успевает винчестер успевает записывать. Причем, и тот и другой являются интерпретируемыми языками. Есть ли способ ускорить эту операцию в AutoIt?




Добавлено:
Сообщение автоматически объединено:

Ура! :laugh:

Я понял, в чем была моя ошибка!

Вместо
Код:
$line2 = $line2 & @CRLF & $line1


нужно писать
Код:
$line2 &= @CRLF & $line1


Действие то же самое, но получается намного быстрее (все равно медленней чем Perl, но не в 500 раз, а всего в 5 раз).



Добавлено:
Сообщение автоматически объединено:

Интересно, почему получается такая огромная разница (на 2 порядка) при практически одинаковом коде :scratch:
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
Suppir
А так:
Код:
Dim $sLine2
$sLine1 = 'Решение городской Думы Краснодара от 23 июня 2011 г. N 14 п. 8 “О внесении изменений в решение городской Думы Краснодара от 28.01.2010 N 69 п. 5 “О дополнительных мерах социальной поддержки отдельных категорий граждан”';
$t = TimerInit()
for $i = 1 to 10000
    $sLine2 &= $sLine1
Next

FileWrite("result_autoit.txt", $sLine2)
ConsoleWrite("Success:" & Round(TimerDiff($t)/ 1000, 2) & @CRLF)


Результат: ~ 0.11 - 0.08
 
Автор
S

Suppir

Продвинутый
Сообщения
967
Репутация
62
Garrett
Да, спасибо, я уже написал, что лучше использовать оператор &= для конкатенации, чем указывать напрямую $line2 = $line2 & @CRLF & $line1
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Suppir [?]
Perl колбасит строки быстрее, чем винчестер успевает записывать
ну на врядли быстрее. по крайней мере мой винт 90 МБ/с держит.
 

SECTOR

Продвинутый
Сообщения
399
Репутация
59
Вот так вроде чуть быстрее при большом количесве циклов
Код:
$sLine1 = 'Решение городской Думы Краснодара от 23 июня 2011 г. N 14 п. 8 “О внесении изменений в решение городской Думы Краснодара от 28.01.2010 N 69 п. 5 “О дополнительных мерах социальной поддержки отдельных категорий граждан”';
$t = TimerInit()

$h = FileOpen("Test.txt",2)

for $i = 1 to 10000
	FileWriteLine($h,$sLine1)
Next

FileClose($h)
ConsoleWrite("Success:" & Round(TimerDiff($t)/ 1000, 3) & @CRLF)
 

AZJIO

Меценат
Меценат
Сообщения
2,878
Репутация
1,194
SECTOR
Вот так вроде чуть быстрее при большом количесве циклов
в два раза медленнее... хотя я так и ожидал, никогда ещё работа с HDD не была быстрее чем работа с ОЗУ.
 

SECTOR

Продвинутый
Сообщения
399
Репутация
59
AZJIO, значит мой HDD работает быстрее моей 256mb ОЗУшки :laugh:

А вообще, разве при использовании FileOpen запись не идет в памяти до FileClose? Никогда не думал об этом, если быть чесным...
 

AZJIO

Меценат
Меценат
Сообщения
2,878
Репутация
1,194
SECTOR
А вообще, разве при использовании FileOpen запись не идет в памяти до FileClose?
Легко проверить: поставил паузу перед FileClose на несколько минут, запустил скрипт, файл появился сразу с размером 2Мб.
 
Верх