- Код: Выделить всё
Mid(sKey, beginLine, iSum) = arrData(0,arrTemp(i))
Mid медленный и плохой. Чуть лучше будет
Mid$. И
намного лучше (но травмоопасно) будет —
RtlMoveMemory. Разница в очках медлительности не как 3—2—1, а как 30—20—1. Но неправильное объявление
RtlMoveMemory может превратить картину в 30—20—25. Правильное объявление — это никаких
As String в аргументах
RtlMoveMemory, а только
As Any/
As Long.
Множественных обращений к элементам массива стоит избегать. Это касается повторяющихся
arrTemp(i) и
arrData(0,arr1Temp(i)). Причем если первое решается использованием переменной, то второе не решается. Но решается использованием процедуры в ByRef-аргументом.
Маленькие буферы под каждую строку матрицы в общем случае хуже, чем один большой однократно выделяемый буфер под все строки. И вообще, по какой-то неведомой причине код написан так, как будто идёт обработка только первой строки массива. Число операций по выделению и перевыделению памяти должно быть предельно минимизировано.
Названия переменных — это отдельный треш. Что за
beginLine? Это звучит как призыв действию, как «начни строку».
cchCopyOffset — вот нормальное название. И вместо
iSum —
cchFragmentLength. Ну и так далее.
alibek писал(а):Можно просто делать изначально большой буфер, а если его вдруг не хватит, то удваивать.
Так допустимо делать, но в данном случае это вредно. Bottleneck в производительности — именно операции выделения памяти под строки. С таким подходом при неоптимальном подборе констант «начальный размер буфера» и «шаг/коэффициент увеличения» на одну строку матрицы может прийтись множество операций выделение
нового строкового буфера + освобождение старого, что почти уровняет производительность с вариантом «тупо конкатенация в цикле». А даже при оптимальном подборе на каждую строку исходной матрицы придётся как минимум две операции выделения, потому что изначально избыточные буфер придётся урезать, а это означает создание нового строкового буфера меньшей длины, копирование и уничтожение старого.