#vba #vb6
#vba #vb6
Вопрос:
При примерно 20 тысячах наблюдений выполнение следующего кода занимает около 7,5 секунд
'Remember time when macro starts
StartTime = Timer
For i = 2 To UBound(avTransposed, 2)
For J = 1 To UBound(avTransposed, 1)
k = IIf(J = 1, k 1, k)
' If J = 1 Then k = k 1
ReDim Preserve TrueUsedRangeArray(1 To Dim2, 1 To k)
TrueUsedRangeArray(J, k) = avTransposed(J, i)
Next
Next
'Determine how many seconds code took to run
SecondsElapsed = Round(Timer - StartTime, 2)
Без строки
k = IIf(J = 1, k 1, k) (или, если J = 1, то k = k 1) это займет менее одной секунды!!
Есть идеи?
Комментарии:
1. В результате тестирования с 400 000 данными это заняло 0,12 секунды. Похоже, есть причина, отличная от проблемы с кодом. Вам потребуется больше информации о ваших данных, чтобы найти причину. Если есть формулы, связанные с ячейкой, это может быть медленным.
2. Dim2 выполняется от 1 до 33. K выполняется от 1 до 20000. avTransposed — это альтернативный массив. Нет формул
3. результат тестирования ваших данных, это заняло 0,41 секунды
4. По
IIf
своей сути медленнее, чем обычныйif
/else
, поскольку он должен оценивать и сохранятьk 1
, даже еслиJ
это не1
так, но это крошечная разница, которая не приведет к огромному расхождению, которое, очевидно, существует.5. Переменные
k
иDim2
не инициализируются перед использованием, по крайней мере, как показано в опубликованном фрагменте кода. Невозможно полностью понять использование массива (и, следовательно, изменение размера массива и, следовательно, возможное влияние на производительность), не зная, как устанавливаются / используются эти переменные.
Ответ №1:
Сохранение ReDim, вероятно, снижает производительность. Каждый раз, когда он используется, он создает новый массив и копирует существующий массив.
Вы можете заранее определить размер TrueUsedRangeArray, что-то вроде следующего
ReDim TrueUsedRangeArray(1 To Ubound(avTransposed, 2), 1 To Ubound(avTransposed, 1))
Комментарии:
1. Не могли бы вы рассказать немного подробнее?
2. Это. Сохранение Redim может быть очень медленным.
Ответ №2:
Слишком много вещей в вашем внутреннем цикле, которые не должны быть там:
For i = 2 To UBound(avTransposed, 2)
k = k 1
ReDim Preserve TrueUsedRangeArray(1 To Dim2, 1 To k)
For J = 1 To UBound(avTransposed, 1)
TrueUsedRangeArray(J, k) = avTransposed(J, i)
Next
Next
Однако, как отмечает Патрик, вам не нужно сохранять redim в цикле, поскольку вы уже знаете конечный размер TrueUsedRangeArray из размеров avTransposed