Сообщение создано: 12. 03. 2015 [12:40]
|
punk
Василий Петров
Создатель темы
Зарегистрирован(а) с: 09.05.2011
Сообщения: 57
|
Добрый день, Роман.
У меня возникла задача объединить множество кусков в одну строку для последующей обработки. Моя программа работала крайне медленно и я решил разобраться. Выяснилось, что операция объединения строк (как S=S+"AAA" так и S+="AAA") снижает свою скорость по мере увеличения размера S. Также выяснилось, что эффективно сначала собирать много маленьких кусочков в куски побольше, а затем уже объединять их. Вот пример программы:
using Special.FLibSYS;
s1=s2="";
sA="QWErtyUIOasdFGHjkl";
// вариант 1 (подклеиваем кусочки "в лоб")
SYS.messErr("strCatTest","timeMark, v1, start time= "+tmFStr(SYS.time(),"%M:%S"));
for (ch1=0;ch1<50000;ch1++)
s1+=sA;
SYS.messErr("strCatTest","timeMark, v1, end (v2 start) time= "+tmFStr(SYS.time(),"%M:%S"));
// вариант 2 (собираем куски среднего размера и их уже собираем в готовую строку)
for (ch1=0;ch1<10;ch1++)
{
s0="";
for (ch2=0;ch2<5000;ch2++)
s0+=sA;
s2+=s0;
}
SYS.messErr("strCatTest","timeMark, v2, end time= "+tmFStr(SYS.time(),"%M:%S"));
SYS.messErr("strCatTest","strSizes: s1="+s1.length+" s2="+s2.length);
Время работы (у меня) отличается в разы. Роман, подскажите, у Вас этот тест тоже даёт значительную разницу затрат времени? Или я неправильно использую встроенную функцию языка и есть специальная функция быстрого приклеивания маленького куска к большой строке?
|
Сообщение создано: 13. 03. 2015 [08:34]
|
roman
Roman Savochenko
Moderator Contributor Developer
Зарегистрирован(а) с: 12.12.2007
Сообщения: 3750
|
"punk" wrote:
У меня возникла задача объединить множество кусков в одну строку для последующей обработки. Моя программа работала крайне медленно и я решил разобраться. Выяснилось, что операция объединения строк (как S=S+"AAA" так и S+="AAA") снижает свою скорость по мере увеличения размера S.
Естественно, больше куски памяти перевыделять и копировать. Операции S=S+"AAA" и S+="AAA" идентичны поскольку последняя в конечном счёте выражается через первую.
"punk" wrote:
Роман, подскажите, у Вас этот тест тоже даёт значительную разницу затрат времени? Или я неправильно использую встроенную функцию языка и есть специальная функция быстрого приклеивания маленького куска к большой строке?
Да, при измерении в мс, получается:
1|strCatTest | timeMark, v1, end (v2 start) time= 5887.149ms
1|strCatTest | timeMark, v2, end time= 188.48ms
1|strCatTest | strSizes: s1=900000 s2=900000
Learn, learn and learn better than work, work and work.
|
Сообщение создано: 26. 03. 2015 [17:04]
|
roman
Roman Savochenko
Moderator Contributor Developer
Зарегистрирован(а) с: 12.12.2007
Сообщения: 3750
|
Вот так получается быстро и именно для таких задач объект IO предусмотрен:
// Вариант 3 (запись в IO)
var utm = 0;
wTm = SYS.time(utm)*1e6 + utm;
IO = SYS.Special.FLibSYS.IO();
for(ch1 = 0; ch1 < 50000; ch1++) IO.write(sA);
wTm1 = SYS.time(utm)*1e6 + utm;
SYS.messInfo("strCatTest", "Direct insert to IO "+IO.string.length+": " + (1e-3*(wTm1-wTm)) + "ms");
Learn, learn and learn better than work, work and work.
|
Сообщение создано: 28. 03. 2015 [17:55]
|
roman
Roman Savochenko
Moderator Contributor Developer
Зарегистрирован(а) с: 12.12.2007
Сообщения: 3750
|
"roman" wrote:
Естественно, больше куски памяти перевыделять и копировать. Операции S=S+"AAA" и S+="AAA" идентичны поскольку последняя в конечном счёте выражается через первую.
Отделил команды S+="AAA" от S=S+"AAA".
Теперь примерно так:
"roman" wrote:
Да, при измерении в мс, получается:
1|strCatTest | timeMark, v1, end (v2 start) time= 58ms
1|strCatTest | timeMark, v2, end time= 65ms
1|strCatTest | strSizes: s1=900000 s2=900000
Learn, learn and learn better than work, work and work.
|