Ускорение вычислений

#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