Страницы: 1
RSS
Оператор With...End With ускоряет код?
 
Привет всем :)

Простой вопрос по VBA: оператор With...End With  (в общем случае) ускоряет выполнение кода или служит просто для удобства при написании?
 
ускоряет написание кода. На выполнение вряд ли сказывается. ЯТД.
 
Не задавался таким вопросом - думаю в любом случае разница будет незначительной.
Но вот буквы кода точно сокращает :)
Кроме того объекты созданные таким способом после использования должны исчезать. Если же занести их в переменную - её/его желательно принудительно убивать, что опять буквы, и что часто забывается.
 
Сказывается. Указатель на объект создается один раз, вместо нескольких.
Я сам - дурнее всякого примера! ...
 
Спасибо за ответы :)
 
а вот, кстати, интересно, а где хранится этот объект? это ссылка?
Живи и дай жить..
 
With ... End With ускоряет код, и тем больше, чем больше вложенных объектов (в виде разделительных точек) охватывает, и чем более медленный доступ к этим объектам.
Вот чисто тестовый, но наглядный пример для сравнения:
Код
Sub Test1()
  Const N = 100000
  Dim i&, t!, x
  t = Timer
  For i = 1 To N
    x = ActiveSheet.Cells.SpecialCells(xlCellTypeVisible).Areas.Count
  Next
  Debug.Print Timer - t
End Sub

Sub Test2()
  Const N = 100000
  Dim i&, t!, x
  t = Timer
  With ActiveSheet.Cells.SpecialCells(xlCellTypeVisible).Areas
    For i = 1 To N
      x = .Count
    Next
  End With
  Debug.Print Timer - t
End Sub


Отличие в скорости - в 100 раз.

Указатель, на который ссылается With, записывается в стековый регистр процессора, доступ к которому очень быстрый. Но по этой же причине не рекомендуется из With ... End With выходить принудительно по GoTo, так как указатель на объект остается в стеке, а сам объект не удаляется из памяти, т.е. образуется утечка памяти.
Изменено: ZVI - 14.09.2013 06:56:03
 
спасибо, Владимир.
Живи и дай жить..
 
Владимир - очередной раз спасибо. Не знал про стековый регистр. Знал, что быстрее доступ(опытным путем), но не знал причину.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
ну.. стековый регистр - это если цикл какой-то немаленький, тогда почувствуешь..

а вот как внутри with .. end with обратиться к самому обекту, им обозначенному?
Живи и дай жить..
 
Владимир, мне кажется не корректное сравнение.
Вот то же самое без With - и скорость вообще не отличается:

Код
Sub Test3()
  Const N = 100000
  Dim i&, t!, x, y&
  t = Timer
  Set x = ActiveSheet.Cells.SpecialCells(xlCellTypeVisible).Areas
  For i = 1 To N
    y = x.Count
  Next
  Debug.Print Timer - t
End Sub
 
Игорь, ну ты чего? Ты просто по-другому установил указатель на объект  :)
Яйца те же, только в профиль  :D  
P.S. Лирика: в ранней молодости, начиная заниматься радиоконструированием, я скрупулезно вникал, что такое электронно-дырочные переходы и прочее подобное. Дальше в жизни оно мне никак не понадобилось. Надо было просто знать, что подавая смещение на базу транзистора, мы регулируем степень его открытости. И незачем тут лезть в физику процесса, я ее никак не изменю. Законы природы.  ;)
pps сравни:
Код
Sub Test3()
  Const N = 100000
  Dim i&, t!, x, y&
  t = Timer
'  Set x = ActiveSheet.Cells.SpecialCells(xlCellTypeVisible).Areas
  For i = 1 To N
    y = ActiveSheet.Cells.SpecialCells(xlCellTypeVisible).Areas.Count
  Next
  Debug.Print Timer - t
End Sub
Изменено: KuklP - 14.09.2013 13:33:11
Я сам - дурнее всякого примера! ...
 
Я так думаю - задавая with мы один раз определяем этот объект, затем обращаемся к нему.
Я сделал это же через переменную.
А вариант
Код
  For i = 1 To N
    y = ActiveSheet.Cells.SpecialCells(xlCellTypeVisible).Areas.Count
  Next

заставляет N раз определять этот объект. Неравноценное соревнование!
 
Ты все правильно понимаешь  :D Или 100000 раз вычислять объект, или использовать один раз вычисленный указатель.
Я сам - дурнее всякого примера! ...
 
Так тема о чём? Что быстрее - указатель через set переменная или with без переменной. Я так понял тему.
 
Гы) Перечитай старттопик.
Я сам - дурнее всякого примера! ...
 
Ну так в чём я не прав?
"With...End With (в общем случае)"
Я обычно поступаю так - можно обойтись без переменной - использую with. Нельзя/неудобно - использую переменную.
Замерил - разницы не увидел.
 
Поддерживаю Игоря, вариант не совсем корректный.
Предлагаю свой со сменой нескольких свойств шрифта ячейки, выигрыш, правда, не столь впечатляющий.
Время по разным видам
With pCell.Font 2,76
With pCell 2,91
Обращение к pCell.Font.ColorIndex, pCell.Font.Bold, pCell.Font.Italic 2,92
Думаю, если изменять больше свойств шрифта, то разница между будет расти. Тестировал по средним для 6 запусков каждого варианта.
Изменено: anvg - 14.09.2013 15:26:49
 
Цитата
Так тема о чём? Что быстрее - указатель через set переменная или with без переменной.
Игорь, может мы по разному видим? Я видел вопрос:
Код
оператор With...End With (в общем случае) ускоряет выполнение кода или служит просто для удобства при написании?
Где ты тут увидел сравнение set и with?
Я сам - дурнее всякого примера! ...
 
Вот привязался к set... :)
Ну пусть будет просто - пишем всюду sheets(1).range(... или по возможности .range(...?
Что будет явно и в N раз быстрее?
 
Я уже не знаю...  :D Игорь, сравни по скорости свой код из 11 поста и он же исправленный из 12. Там мы в каждом проходе цикла вычисляем объект:
Код
ActiveSheet.Cells.SpecialCells(xlCellTypeVisible).Areas
Неужели твой код не быстрей?
Я сам - дурнее всякого примера! ...
 
Я понял про "вычисляем". Не понял зачем. Как это связано с использованием или неиспользованием with?
Можно ведь было ещё что-нибудь позаковыристей придумать, что-нибудь поглубже в недрах дерева...
А если так погонять:
Код
Sub Test1()
  Const N = 100000
  Dim i&, t!, x
  t = Timer
  For i = 1 To N
    x = Sheets(1).Index
  Next
  Debug.Print Timer - t
End Sub



Sub Test2()
  Const N = 100000
  Dim i&, t!, x
  t = Timer
  With Sheets(1)
    For i = 1 To N
      x = .Index
    Next
  End With
  Debug.Print Timer - t
End Sub

В общем ничего принципиально не изменил....
Да, с with быстрее. Но не всегда.
Страницы: 1
Наверх