Домашняя страница Undo Do New Save Карта сайта Обратная связь Поиск по форуму
МИР MS EXCEL - Гость.xls

Вход

Регистрация

Напомнить пароль

 

= Мир MS Excel/Диапазоны против Массивов - Мир MS Excel

Старая форма входа
  • Страница 1 из 1
  • 1
Модератор форума: китин  
Диапазоны против Массивов
Skif-F Дата: Вторник, 26.05.2015, 23:50 | Сообщение № 1
Группа: Проверенные
Ранг: Участник
Сообщений: 73
Репутация: 14 ±
Замечаний: 0% ±

Excel 2007, 2010, 2013, 2016
В теме Подсчёт совпадений... была поднята тема "что лучше при работе в VBA - использовать встроенные функции Excel или же взяв данные в массив обрабатывать их в массиве?" Тема была поднята не автором темы, а двумя желающими помочь форумчанами.
Суть дискуссии состояла в выборе более быстрого варианта из следующих:
[vba]
Код
' загоняем в словарь только нужное, а не все подряд...
For Each c In .Columns(2).SpecialCells(xlCellTypeFormulas)
     Dict.Add c.Value, c.Row
Next
[/vba]
или
[vba]
Код
'Снимаем с листа данные
With Worksheets(conИсходныйЛист)
     Исх = .Range("A1:W" & .Cells(.Rows.Count, 3).End(xlUp).Row).Value
End With

'Подготавливаем словарь для ускорения работы
For i = 3 To UBound(Исх)
     If Исх(i, 3) <> "" Then
         'Если в третьем столбце не пусто, то запоминаем номер строки
         СловарьСтрок.Add Исх(i, 3), i
     End If
Next i
[/vba]
Чтобы найти истину, были написаны тесты, сведённые в книгу Tests.xls (во вложении). В файле расположена исходная таблица данных на листе «ВОЙНАМИР» и модули в VBA-проекте:
 
Ответить
СообщениеВ теме Подсчёт совпадений... была поднята тема "что лучше при работе в VBA - использовать встроенные функции Excel или же взяв данные в массив обрабатывать их в массиве?" Тема была поднята не автором темы, а двумя желающими помочь форумчанами.
Суть дискуссии состояла в выборе более быстрого варианта из следующих:
[vba]
Код
' загоняем в словарь только нужное, а не все подряд...
For Each c In .Columns(2).SpecialCells(xlCellTypeFormulas)
     Dict.Add c.Value, c.Row
Next
[/vba]
или
[vba]
Код
'Снимаем с листа данные
With Worksheets(conИсходныйЛист)
     Исх = .Range("A1:W" & .Cells(.Rows.Count, 3).End(xlUp).Row).Value
End With

'Подготавливаем словарь для ускорения работы
For i = 3 To UBound(Исх)
     If Исх(i, 3) <> "" Then
         'Если в третьем столбце не пусто, то запоминаем номер строки
         СловарьСтрок.Add Исх(i, 3), i
     End If
Next i
[/vba]
Чтобы найти истину, были написаны тесты, сведённые в книгу Tests.xls (во вложении). В файле расположена исходная таблица данных на листе «ВОЙНАМИР» и модули в VBA-проекте:

Автор - Skif-F
Дата добавления - 26.05.2015 в 23:50
Skif-F Дата: Среда, 27.05.2015, 00:01 | Сообщение № 2
Группа: Проверенные
Ранг: Участник
Сообщений: 73
Репутация: 14 ±
Замечаний: 0% ±

Excel 2007, 2010, 2013, 2016
На основании вышеуказанных тестов можно сделать следующие выводы:
1. Циклы типа[vba]
Код
Dim c As Range
For Each c In Range(...)
     ...
Next
[/vba]жутко медленная вещь, поскольку при каждой итерации цикла заново создаётся объект типа Range, к которому обращается тело цикла (это уже многократно обсуждалось на просторах Интернета);
2. Интересная идея по применению SpecialCells() абсолютно нивелируется необходимостью многократных обращений к диапазонам;
3. Использование функции WorksheetFunction.CountA почему-то не повлияло на итоговую производительность программы при всех своих очевидных плюсах;
4. Функция UBound очень медленная. Поэтому в времякритичных частях кода лучше отслеживать размер массива через дополнительную переменную.
[p.s.]Код тестировался в Windows 7, Excel 2007 x32. Будет интересно узнать выводы и наблюдения в других системах.
 
Ответить
СообщениеНа основании вышеуказанных тестов можно сделать следующие выводы:
1. Циклы типа[vba]
Код
Dim c As Range
For Each c In Range(...)
     ...
Next
[/vba]жутко медленная вещь, поскольку при каждой итерации цикла заново создаётся объект типа Range, к которому обращается тело цикла (это уже многократно обсуждалось на просторах Интернета);
2. Интересная идея по применению SpecialCells() абсолютно нивелируется необходимостью многократных обращений к диапазонам;
3. Использование функции WorksheetFunction.CountA почему-то не повлияло на итоговую производительность программы при всех своих очевидных плюсах;
4. Функция UBound очень медленная. Поэтому в времякритичных частях кода лучше отслеживать размер массива через дополнительную переменную.
[p.s.]Код тестировался в Windows 7, Excel 2007 x32. Будет интересно узнать выводы и наблюдения в других системах.

Автор - Skif-F
Дата добавления - 27.05.2015 в 00:01
ikki Дата: Среда, 27.05.2015, 00:51 | Сообщение № 3
Группа: Друзья
Ранг: Старожил
Сообщений: 1906
Репутация: 504 ±
Замечаний: 0% ±

Excel 2003, 2010
я один не вижу приложенных файлов?

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


помощь по Excel и VBA
ikki@fxmail.ru, icq 592842413, skype alex.ikki
 
Ответить
Сообщениея один не вижу приложенных файлов?

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

Автор - ikki
Дата добавления - 27.05.2015 в 00:51
Skif-F Дата: Среда, 27.05.2015, 00:58 | Сообщение № 4
Группа: Проверенные
Ранг: Участник
Сообщений: 73
Репутация: 14 ±
Замечаний: 0% ±

Excel 2007, 2010, 2013, 2016
UBound используется всего один раз

Она используется в цикле. А когда я заменил её на переменную (модуль Заполнение3), то получил двукратное снижение времени, что сравнимо с полным отказом от неё (модуль Заполнение2)
 
Ответить
Сообщение
UBound используется всего один раз

Она используется в цикле. А когда я заменил её на переменную (модуль Заполнение3), то получил двукратное снижение времени, что сравнимо с полным отказом от неё (модуль Заполнение2)

Автор - Skif-F
Дата добавления - 27.05.2015 в 00:58
ikki Дата: Среда, 27.05.2015, 01:00 | Сообщение № 5
Группа: Друзья
Ранг: Старожил
Сообщений: 1906
Репутация: 504 ±
Замечаний: 0% ±

Excel 2003, 2010
не, ну я, конечно, верю.
но
не вижу приложенных файлов


помощь по Excel и VBA
ikki@fxmail.ru, icq 592842413, skype alex.ikki
 
Ответить
Сообщениене, ну я, конечно, верю.
но
не вижу приложенных файлов

Автор - ikki
Дата добавления - 27.05.2015 в 01:00
Skif-F Дата: Среда, 27.05.2015, 01:09 | Сообщение № 6
Группа: Проверенные
Ранг: Участник
Сообщений: 73
Репутация: 14 ±
Замечаний: 0% ±

Excel 2007, 2010, 2013, 2016
Глючу! Вот файл...
К сообщению приложен файл: Tests.zip (83.5 Kb)
 
Ответить
СообщениеГлючу! Вот файл...

Автор - Skif-F
Дата добавления - 27.05.2015 в 01:09
ikki Дата: Среда, 27.05.2015, 01:27 | Сообщение № 7
Группа: Друзья
Ранг: Старожил
Сообщений: 1906
Репутация: 504 ±
Замечаний: 0% ±

Excel 2003, 2010
win7 32, excel 2010
работает. само собой - одна из кнопок даёт ошибку, ну да бог с ней - вроде бы не нужна.

На основании вышеуказанных тестов можно сделать следующие выводы
честное слово - удивляюсь, как это у Вас получилось.
в смысле - сделать выводы при таких результатах.

1) объем исходных данных слишком мал для более-менее адекватного теста. не спасает даже "десятикратность", т.к. всё равно мало, зато погрешностей, вызванных не разницей в алгоритмах, а накладными расходами на вызов функций и т.п. - прибавляется.
2) разброс результатов чудовищный. у меня при четырех-пяти запусках получилось от 68 "тиксов" до 141. причем в некоторых запусках вариант с заменой ubound на переменную был чуть быстрее, в некоторых - медленнее. что, имхо, ещё раз подтверждает вывод о невозможности делать серьезные "выводы" при таком тестировании.

все - имхо.
не для спора.


помощь по Excel и VBA
ikki@fxmail.ru, icq 592842413, skype alex.ikki
 
Ответить
Сообщениеwin7 32, excel 2010
работает. само собой - одна из кнопок даёт ошибку, ну да бог с ней - вроде бы не нужна.

На основании вышеуказанных тестов можно сделать следующие выводы
честное слово - удивляюсь, как это у Вас получилось.
в смысле - сделать выводы при таких результатах.

1) объем исходных данных слишком мал для более-менее адекватного теста. не спасает даже "десятикратность", т.к. всё равно мало, зато погрешностей, вызванных не разницей в алгоритмах, а накладными расходами на вызов функций и т.п. - прибавляется.
2) разброс результатов чудовищный. у меня при четырех-пяти запусках получилось от 68 "тиксов" до 141. причем в некоторых запусках вариант с заменой ubound на переменную был чуть быстрее, в некоторых - медленнее. что, имхо, ещё раз подтверждает вывод о невозможности делать серьезные "выводы" при таком тестировании.

все - имхо.
не для спора.

Автор - ikki
Дата добавления - 27.05.2015 в 01:27
Skif-F Дата: Среда, 27.05.2015, 06:35 | Сообщение № 8
Группа: Проверенные
Ранг: Участник
Сообщений: 73
Репутация: 14 ±
Замечаний: 0% ±

Excel 2007, 2010, 2013, 2016
объем исходных данных слишком мал

Большой объём не положить на форум. При экспериментах расширял до 500 ячеек, заполняя их произвольными данными.
разброс результатов чудовищный

Не наблюдал большого разброса результата, максимум процентов 30. Но при всём этом соотношение разных вариантов держится на похожем уровне. Например для теста программ: 64, 39, 39, 130 "тиков" (типовой результат)
не для спора

Основной "спор", естественно, между исходными вариантами, а тут двукратное преимущество "массивного" метода над "диапазонным"
 
Ответить
Сообщение
объем исходных данных слишком мал

Большой объём не положить на форум. При экспериментах расширял до 500 ячеек, заполняя их произвольными данными.
разброс результатов чудовищный

Не наблюдал большого разброса результата, максимум процентов 30. Но при всём этом соотношение разных вариантов держится на похожем уровне. Например для теста программ: 64, 39, 39, 130 "тиков" (типовой результат)
не для спора

Основной "спор", естественно, между исходными вариантами, а тут двукратное преимущество "массивного" метода над "диапазонным"

Автор - Skif-F
Дата добавления - 27.05.2015 в 06:35
SLAVICK Дата: Среда, 27.05.2015, 10:04 | Сообщение № 9
Группа: Модераторы
Ранг: Старожил
Сообщений: 2290
Репутация: 766 ±
Замечаний: 0% ±

2019
На своих разработках пришел к выводу, что массивы однозначно быстрее диапазонов.
Особенно если все сделать по уму без лишних циклов.
А массивы в сочетании с словарем получается вообще бомба. :D
Полностью согласен с ikki, для того чтобы по достоинству оценить их преимущества нужно работать с большими диапазонами (больше 500тыс строк).
Когда-то я пользовался ВПР... сейчас практически исключил из повседневной работы формулы... все расчеты повседневных отчетов перевел на массивы+ словарь B) . Самый лучший эффект получается когда сначала считываешь ВСЕ данные сразу в разные массивы, а потом их там обрабатываешь...
Преимущество на лицо... теперь за это же время можно, как минимум, выпить чашечку кофе, или написать пару - тройку сообщений на форуме :D


Иногда все проще чем кажется с первого взгляда.

Сообщение отредактировал SLAVICK - Среда, 27.05.2015, 10:06
 
Ответить
СообщениеНа своих разработках пришел к выводу, что массивы однозначно быстрее диапазонов.
Особенно если все сделать по уму без лишних циклов.
А массивы в сочетании с словарем получается вообще бомба. :D
Полностью согласен с ikki, для того чтобы по достоинству оценить их преимущества нужно работать с большими диапазонами (больше 500тыс строк).
Когда-то я пользовался ВПР... сейчас практически исключил из повседневной работы формулы... все расчеты повседневных отчетов перевел на массивы+ словарь B) . Самый лучший эффект получается когда сначала считываешь ВСЕ данные сразу в разные массивы, а потом их там обрабатываешь...
Преимущество на лицо... теперь за это же время можно, как минимум, выпить чашечку кофе, или написать пару - тройку сообщений на форуме :D

Автор - SLAVICK
Дата добавления - 27.05.2015 в 10:04
ikki Дата: Среда, 27.05.2015, 12:38 | Сообщение № 10
Группа: Друзья
Ранг: Старожил
Сообщений: 1906
Репутация: 504 ±
Замечаний: 0% ±

Excel 2003, 2010
то, что массивы быстрее - это даже обсуждать странно ))

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

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


помощь по Excel и VBA
ikki@fxmail.ru, icq 592842413, skype alex.ikki
 
Ответить
Сообщението, что массивы быстрее - это даже обсуждать странно ))

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

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

Автор - ikki
Дата добавления - 27.05.2015 в 12:38
Skif-F Дата: Среда, 27.05.2015, 12:57 | Сообщение № 11
Группа: Проверенные
Ранг: Участник
Сообщений: 73
Репутация: 14 ±
Замечаний: 0% ±

Excel 2007, 2010, 2013, 2016
массивы однозначно быстрее диапазонов

Просто некоторые не верят... :(
 
Ответить
Сообщение
массивы однозначно быстрее диапазонов

Просто некоторые не верят... :(

Автор - Skif-F
Дата добавления - 27.05.2015 в 12:57
ikki Дата: Среда, 27.05.2015, 13:15 | Сообщение № 12
Группа: Друзья
Ранг: Старожил
Сообщений: 1906
Репутация: 504 ±
Замечаний: 0% ±

Excel 2003, 2010
и Вас это так сильно огорчает? :)
сколько времени Вы потратили на этот файл? просто любопытно...


помощь по Excel и VBA
ikki@fxmail.ru, icq 592842413, skype alex.ikki
 
Ответить
Сообщениеи Вас это так сильно огорчает? :)
сколько времени Вы потратили на этот файл? просто любопытно...

Автор - ikki
Дата добавления - 27.05.2015 в 13:15
Skif-F Дата: Среда, 27.05.2015, 14:42 | Сообщение № 13
Группа: Проверенные
Ранг: Участник
Сообщений: 73
Репутация: 14 ±
Замечаний: 0% ±

Excel 2007, 2010, 2013, 2016
Может быть кому-нибудь поможет!
В сумме (раз-, до-, про- и переработка) часов восемь-то ушло :)
Зато сам кое-что новое узнал - про тот-же UBound, что не стоит его вставлять в цикл. А также то, что увеличение массива почти не влияет на скорость (как минимум на небольших массивах) - возможно VBA сразу выделяет память с запасом!
 
Ответить
СообщениеМожет быть кому-нибудь поможет!
В сумме (раз-, до-, про- и переработка) часов восемь-то ушло :)
Зато сам кое-что новое узнал - про тот-же UBound, что не стоит его вставлять в цикл. А также то, что увеличение массива почти не влияет на скорость (как минимум на небольших массивах) - возможно VBA сразу выделяет память с запасом!

Автор - Skif-F
Дата добавления - 27.05.2015 в 14:42
AndreTM Дата: Среда, 27.05.2015, 23:22 | Сообщение № 14
Группа: Друзья
Ранг: Старожил
Сообщений: 1762
Репутация: 501 ±
Замечаний: 0% ±

2003 & 2010
Ну, про то, что не следует использовать for each при обработке больших наборов данных - исписаны тысячи страниц... :)
Обращаю внимание - именно большого диапазона как источника данных для цикла.
И вообще, "прямая" обработка данных в объектной модели (на листе) всегда проигрывает подходу "прочитать-обработать-записать результат" даже начиная с достаточно небольших объемов.
Нечто похожее мы обсуждали и там.

А переменные (и массивы) в VBA всегда динамические, так что "скоростное переопределение" - это достоинства MemoryAllocator, а никак не хитрых алгоритмов


Skype: andre.tm.007
Donate: Qiwi: 9517375010
 
Ответить
СообщениеНу, про то, что не следует использовать for each при обработке больших наборов данных - исписаны тысячи страниц... :)
Обращаю внимание - именно большого диапазона как источника данных для цикла.
И вообще, "прямая" обработка данных в объектной модели (на листе) всегда проигрывает подходу "прочитать-обработать-записать результат" даже начиная с достаточно небольших объемов.
Нечто похожее мы обсуждали и там.

А переменные (и массивы) в VBA всегда динамические, так что "скоростное переопределение" - это достоинства MemoryAllocator, а никак не хитрых алгоритмов

Автор - AndreTM
Дата добавления - 27.05.2015 в 23:22
Sashagor1982 Дата: Четверг, 28.05.2015, 20:56 | Сообщение № 15
Группа: Проверенные
Ранг: Обитатель
Сообщений: 287
Репутация: -6 ±
Замечаний: 0% ±

Excel 2007
Skif-F, Небольшой вопрос, вы где изучали VBA? Или самоучка?
 
Ответить
СообщениеSkif-F, Небольшой вопрос, вы где изучали VBA? Или самоучка?

Автор - Sashagor1982
Дата добавления - 28.05.2015 в 20:56
Skif-F Дата: Четверг, 28.05.2015, 21:24 | Сообщение № 16
Группа: Проверенные
Ранг: Участник
Сообщений: 73
Репутация: 14 ±
Замечаний: 0% ±

Excel 2007, 2010, 2013, 2016
по F1, потом книги читал и много-много экспериментов делал :D
Разве кто-то изучает VBA иначе?
 
Ответить
Сообщениепо F1, потом книги читал и много-много экспериментов делал :D
Разве кто-то изучает VBA иначе?

Автор - Skif-F
Дата добавления - 28.05.2015 в 21:24
  • Страница 1 из 1
  • 1
Поиск:

Яндекс.Метрика Яндекс цитирования
© 2010-2024 · Дизайн: MichaelCH · Хостинг от uCoz · При использовании материалов сайта, ссылка на www.excelworld.ru обязательна!