Option Base 1
Option Explicit
Option Private Module
'====================================================================================================
Dim x, t!, tt!, nE&, nC&
Const tx$ = "TestValue", nEl& = 10000, nCyc& = 1000
'====================================================================================================
Sub TestArray()
Dim arr()
tt = Timer: t = Timer
ReDim arr(nEl)
For nE = 1 To nEl
arr(nE) = tx
Next nE
Debug.Print "Array", "Fill", Format$(Timer - t, "0.000 sec") ' 0.000
t = Timer
For nC = 1 To nCyc
For nE = 1 To nEl
x = arr(nE)
Next nE
Next nC
Debug.Print "Array", "Get", Format$(Timer - t, "0.000 sec") ' 0.438
Debug.Print "Array", "Total", Format$(Timer - tt, "0.000 sec") ' 0.438
End Sub
'====================================================================================================
Sub TestDic()
Dim dic As New Dictionary
tt = Timer: t = Timer
For nE = 1 To nEl
dic.Add nE, tx
Next nE
Debug.Print "Dic", "Fill", Format$(Timer - t, "0.000 sec") ' 0.000
t = Timer
For nC = 1 To nCyc
For nE = 1 To nEl
x = dic(nE)
Next nE
Next nC
Debug.Print "Dic", "Get", Format$(Timer - t, "0.000 sec") ' 1.484
Debug.Print "Dic", "Total", Format$(Timer - tt, "0.000 sec") ' 1.484
End Sub
'====================================================================================================
Sub TestColl()
Dim coll As New Collection
tt = Timer: t = Timer
For nE = 1 To nEl
coll.Add tx, CStr(nE)
Next nE
Debug.Print "Coll", "Fill", Format$(Timer - t, "0.000 sec") ' 0.031
t = Timer
For nC = 1 To nCyc
For nE = 1 To nEl
x = coll(CStr(nE))
Next nE
Next nC
Debug.Print "Coll", "Get", Format$(Timer - t, "0.000 sec") ' 14.195
Debug.Print "Coll", "Total", Format$(Timer - tt, "0.000 sec") ' 14.226
End Sub
'====================================================================================================
Сравнил скорости на "обычных" объёмах данных. При увеличении количества элементов и циклов, словарь быстро и предсказуемо сходит на нет, а коллекции вообще нельзя использовать (тоже предсказуемо — они годятся вместо словарей если ключей более 100 тыс)
Зачем:
Если ключами являются целые числа и пропусков между ними немного, то предпочтительнее использовать массивы - это проще, не требует дополнительных библиотек и заметно быстрее (тем больше, чем больше у вас ключей и вызовов получения данных по ключам) Даже, если ключами являются НЕ целые числа или между большие пропуски, то всегда можно использовать дополнительный словарь соответствий "ключ-индекс" для конвертации
Реальное применение у меня:
Обновление данных из закрытых книг Словарями (на самом деле "картами" от bedvit'а по ссылке выше, но суть та же) собираю суммы по ключам (текстовые), конвертирую ключи в целочисленные индексы, по этим индексам заполняю массивы и храню в памяти. Пишу функции листа, возвращающие по индексу из массива нужную сумму Работает мгновенно, на пересчёт никак не влияет Да - гораздо проще и без конвертирования было бы сразу выгрузить на лист значения, но иногда это очень проблематично и UDF гораздо предпочтительнее из-за гибкости (её может ввести любой пользователь там, где ему это нужно)
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
А нет ли ошибки при проведении эксперимента? Если я правильно понимаю, то эту часть Вы используется, чтобы понять, сколько времени потребуется на поиск nCyc элементов в массиве длиной nEl.
Код
For nC = 1 To nCyc
For nE = 1 To nEl
x = arr(nE)
Next nE
Next nC
И сравниваете со временем, которое потребуется на поиск nCyc элементов в словаре на nEl элементов. И для этого используете
Код
For nC = 1 To nCyc
For nE = 1 To nEl
x = dic(nE)
Next nE
Next nC
Мне кажется, это неправильно. Эта конструкция ищет в словаре "nEl * nCyc" раз. А нам, если не ошибаюсь, нужно что-то вроде
Код
For nC = 1 To nCyc
x = dic(nC)
Next nC
PS Такие эксперименты одобряю. Соррян, если я где-то что-то недопонял.
МатросНаЗебре, приветствую и спасибо за внимание к теме!
Код
For nC = 1 To nCyc ' в цикле nCyc раз …
For nE = 1 To nEl ' ищем каждое из nEl элементов в массиве/словаре/коллекции
Next nE
Next nC
или, проще говоря, мы пишем значение (объект содержит) в массив/словарь/коллекцию nEl раз, а считываем nEl * nCyc раз (10 тыс элементов* 1 тыс раз = 10 млн вызовов для примера)
В данном случае никакого перебора массива для поиска значения НЕТ (было бы заметно дольше словаря) и значение берётся по индексу (в качестве ключа) массива напрямую
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄