Excel VBA производительность функции листа против кода, для массивов - PullRequest
2 голосов
/ 14 марта 2019

В стремлении ускорить мой код VBA я искал методы онлайн. Множество методов проходит мимо, и один из них, который продолжает возвращаться, похоже, использует функции листа вместо кода , где это возможно.

Мой опыт, однако, противоречит этому совету. Я считаю, что функции листа работают, как правило, медленнее, чем мой код . Мой простой тест, показанный ниже, показывает, что код примерно в два раза быстрее, чем функция листа. Я нашел те же результаты с другими функциями, такими как MATCH.

Мой вопрос в том, склонны ли вы, пользователи VBA, использовать функции кода или рабочего листа? Есть ли причины использовать функции над кодом (кроме пары строк дополнительного кода)?

Sub testSum()

    Dim testarray(0 To 10000) As Variant
    Dim val As Variant
    Dim valSum As Variant
    Dim i As Long, j As Long
    Dim t As Single

    ' create testarray
    For i = 0 To 10000
        testarray(i) = Rnd
    Next
    For i = 0 To 10000 Step 100
        testarray(i) = "text"
    Next

    ' measure code
    t = Timer
    For j = 1 To 10000
        valSum = 0
        For Each val In testarray
            If IsNumeric(val) Then valSum = valSum + val
        Next
    Next
    Debug.Print "Array: ", Int(valSum), Timer - t

    ' measure function
    t = Timer
    For j = 1 To 10000
        valSum = 0
        valSum = Application.WorksheetFunction.Sum(testarray)
    Next
    Debug.Print "Sum: ", Int(valSum), Timer - t

End Sub

Ответы [ 2 ]

1 голос
/ 15 марта 2019

Я предпочитаю использовать функцию листа в листе. Измерение функции в макросе является несправедливым тестом, так как среда VBA должна переключиться на среду Excel, чтобы получить результаты, и это добавляет издержки, которых нет в противном случае.

Как общее правило кодирования, мои приоритеты:

  • использовать собственные формулы Excel, включая настройку вспомогательных ячеек или столбцы.
  • использовать VBA с массивами
  • использовать VBA с диапазонами

В качестве теста:

  • установить 10000 строк со случайными числами
  • настройте формулу в одной ячейке (B1) =Sum(A1:A10000)
  • выберите B1 и вычислите ячейку

Настройка макроса - ниже приведен быстрый и грязный код, основанный на приведенном выше коде, - он может быть более точным при использовании правильно определенных диапазонов и Option Explicit.

Sub TestNativeSpeed()
    Dim j As Long
    Dim t As Single
    t = Timer
    For j = 1 To 10000
        Range("B1").Dirty
    Next
    Debug.Print "Native Sum: ", Int(Range("B1").Value), Timer - t
End Sub

Я настроил свои ячейки по формуле =Rand() и получил результаты (только один прогон):

Собственная сумма: 4990 16,53125

Я сбросил их только до значений (в соответствии с вашим кодом) и получил результаты (только за один прогон):

Собственная сумма: 4990 1,765625

Я запустил ваш код и получил (только один запуск):

Массив: 4917 4,386719

Сумма: 4917 27,73438

Вышесказанное показывает, что Native Excel обычно является самым быстрым и наиболее эффективным подходом. Но массивы (где не нужно постоянно переключаться между моделями VBA и Excel) являются следующими в плане эффективности.

0 голосов
/ 14 марта 2019

Я почти исключительно использую код.

Возможно, это проблема, но я ненавижу использовать функции, потому что я нахожу, что мне всегда приходится возвращаться и редактировать биты, и это просто сбивает с толку, где я могу просто бездельничатьс одним Sub, если я использую код.

Чтобы ответить на ваш код, я, скорее всего, скажу, просто используйте массивы для суммирования - это потеряет несколько picoSeconds

Попробуйте и используйте Code Review , чтобы эти умственные способности улучшили вашу скорость

...