Является ли низкая производительность автоматического создания экземпляров Excel VBA мифом? - PullRequest
11 голосов
/ 13 декабря 2011

Принято считать, что использование такой конструкции, как Dim dict As New Dictionary, хуже по производительности, чем Dim dict As Dictionary / Set dict = New Dictionary.

Объяснение заключается в том, что первый пример - автоинстанцирование - откладывает инстанцирование до первого использованияпеременная dict.И, таким образом, каждый раз, когда dict ссылается, скомпилированный код должен сначала проверить, равно ли dict Ничему.

Но мне приходит в голову, что скомпилированный код делает это в любом случае.Каждый раз, когда вы пытаетесь использовать ссылку на объект, вы получите сообщение об ошибке Nothing.

Итак, в знак уважения к науке, я провел несколько тестов.И результаты показывают, что между этими двумя подходами нет разницы в производительности.(Запуск в Excel 2007)

Вызовите «создать словарь и добавить 2 элемента» 100 000 раз.

  • Явное: 16 891 мс / Авто: 16 797 мс (АвтоНа 94 мс быстрее)
  • Явный: 16,797 мс / Авто: 16,781 мс (Авто на 16 мс быстрее)

Обратный порядок тестовых вызовов:

  • Авто:16 666 мс / явный: 16 812 мс (автоматический на 46 мс быстрее)
  • автоматический: 16 828 мс / явный: 16 813 мс (явный на 15 мс быстрее)

вызов "создать словарь и добавить6 предметов "100 000 раз.

  • Авто: 17,437 мс / явное: 17,407 мс (явное на 30 мс быстрее)
  • Авто: 17,343 мс / явное: 17,360 мс (автоматическое 17 мсбыстрее)

Создать словарь и добавить 100 000 элементов.

  • Авто: 391 мс / Явное: 391 мс (то же самое)

Создание словаря и добавление 1 000 000 элементов.

  • Авто: 57 609 мс / явное: 58 172 мс (быстрее на 563 мс)
  • Явное: 57 343 мс / авто: 57,422мс (явныйНа 79 мс быстрее)

Я не вижу ничего, что указывало бы на то, что автоинстанцирование плохо работает по сравнению с явным инстанцированием.(По понятным причинам, по другим причинам я бы избегал автоинстанцирования, но мне просто интересен угол производительности здесь.)

Так это миф?

ОБНОВЛЕНИЕ

Позвольте мне изложить, почему аргумент производительности не имеет смысла для меня.Говорят, что

x.Add("Key", "Item")

в автоматически создаваемом объекте эквивалентно следующему:

If x is Nothing then
    Set x = New Dictionary
End If
x.Add("Key", "Item")

, что делает его похожим на «пугающие накладные расходы», если вы вызываете эту тысячураз.Но в случае явного создания экземпляра это именно та форма логики, которая генерируется в скомпилированной версии кода:

If x is Nothing Then
    Err.Raise "Object variable not set..."
End If
x.Add("Key", "Item")

Это не обязательно означает, что auto более длинен, поэтому я спрашиваю,в этом была какая-то правда.Интересно, нашел ли я еще один из многих непроверенных мифов о производительности?

1 Ответ

5 голосов
/ 13 декабря 2011

Я знаю, что есть святой путь, если это нормально или не тускнеть как новый, но я никогда не слышал, чтобы об этом говорили, что это приводит к плохой производительности. Краткий ответ: «Не совсем». Да, он засоряет ваш код ненужными проверками, чтобы увидеть, не является ли он Ничем, но вы не заметите разницу в скорости благодаря современным машинам. Это все равно, что сказать: «зацикливание более 10000 символов быстрее, чем 10001. Чтобы увидеть разницу, вам нужно зацикливать свои тесты в более высоких терминах, таких как миллионы и десятки миллионов.

При том, что Дим как Новый осуждается, но не по соображениям производительности.

  • Вы теряете способность контролировать, когда она инициализируется
  • Вы теряете возможность проверить, является ли объект ничем
  • Разница в скорости или нет, это засоряет ваш код ненужной проверкой

Конечно, если вы просто используете VBA для автоматизации какого-либо содержимого рабочего листа или манипулирования данными, вы, вероятно, не будете об этом заботиться, но в тот момент, когда вы посмотрите на более сложный код, теряете возможность проверить, является ли объект Nothing и не контроль, когда он инициализирован, огромен и может генерировать неожиданное поведение, не говоря уже о том, чтобы тестировать боль в заднице. Все это для сохранения нескольких строк кода.

Тогда есть микро-оптимизаторы, которые будут утверждать, что добавление в ваш код ненужного кода приводит к снижению производительности. Хотя в некотором смысле они правы, в этом случае вы, скорее всего, сэкономите 0,000000001 секунды.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...