, с которой все началось (изменено Sanja)
Вопрос был:
ответ, по-прежнему — нет. Это ограничение [на данный момент] никак обойти не удалось.
Да, testuser, представил альтернативный вариант. За это (и вообще за подобные изыскания) ему большое спасибо. Но это никак не влияет на ограничение из вопроса. И что там по скорости? У меня есть большие сомнения, что такой "прямой доступ" будет быстрее классического подхода со словарями.
Ещё пример:
Карты ("суперсловари" std::unordered_map) от bedvit (о чём он пишет в .
Получение значения там обязательно даже просто для его просмотра/чтения.
О задаче:
Использование массивов разной величины в качестве значений словаря — в большинстве случаев является плохой идеей. Постоянный ReDim Preserve не меньше сказывается на замедлении, чем, непосредственно, присвоение массива переменной. Если тип переменной-массива соответствует типу массива в словаре, то, конечно, будет быстрее. Не нужно работать на варианте, если можно задать специальный тип.
Я подобный вопрос разбирал на задаче "СцепитьЕсли" — там, как раз нужно копить строки по каждому ключу.
Оптимальные варианты для подобных задач:
1. В качестве значения накапливать строку.
s = s & sep & i (Или dic(sKey) = dic(sKey) & sep & i ). Где i — Это очередной индекс вспомогательного одномерного строкового массива.
То есть, чтобы не тратить время на сцепку строк (они могут быть очень длинными), мы сцепляем индексы массива (указатели на эти строки в массиве, если угодно). Да — потом придётся прогнать ещё один цикл по каждой строке с индексами, чтобы их заменить на сами значения, то тесты показывали, что это заметно быстрее.
2. Вообще не хранить строки в качестве значений словаря.
Храним в словаре указатели (индексы массива) на строки в отдельном строковом массиве. Так и извлекать ничего не нужно будет. В этом массиве строки формируем по принципу из п.1 — с помощью ещё одного вспомогательного массива.
3. Отсортировать массив. Самый простой и быстрый вариант.
Отсортировать массив по ключам. В этом случае, у нас будет тольлко один буферный строковый массив — для каждого ключа по почереди. Кладём строки в этом массив и, после окончания очередного ключа, делаем редим и сцепляем.
Это сработает, если у вас есть сортер от bedvit'а. В противном случае, время сортировки вполне может быть больше времени вариантов 1 и 2. Более того, если вам потом нужно эти агрегированные строки всё-равно добавить в словарь (например, чтобы проставить их по ключам на листе), то добавление пар произойдёт заметно быстрее. .
Join строкового массива очень быстрый. Но было бы ещё быстрее, если бы была возможность задать индексы строк массива для сцепки — это бы позволило избежать ReDim Preserve и позволило бы вообще собрать все значения в один массив, в другом двумерном (Long) массиве (в том же цикле) запомнить индекс первого и последнего элемента по ключу и потом просто отдать в библу, чтобы "сделала красиво" (ил прогнать в цикле на стороне VBA).
Для подробного разбора вопроса агрегации строк по ключу я, когда-нибудь сделаю отдельную тему.
UPD: так же она
. Но там ещё много работы нужно проделать …
Вопрос был:
| Цитата |
|---|
| Sanja: Как (и можно ли в принципе), напрямую, без передачи Массива в переменную, изменить какое нибудь его значение? |
Да, testuser, представил альтернативный вариант. За это (и вообще за подобные изыскания) ему большое спасибо. Но это никак не влияет на ограничение из вопроса. И что там по скорости? У меня есть большие сомнения, что такой "прямой доступ" будет быстрее классического подхода со словарями.
Ещё пример:
Карты ("суперсловари" std::unordered_map) от bedvit (о чём он пишет в .
Получение значения там обязательно даже просто для его просмотра/чтения.
О задаче:
Использование массивов разной величины в качестве значений словаря — в большинстве случаев является плохой идеей. Постоянный ReDim Preserve не меньше сказывается на замедлении, чем, непосредственно, присвоение массива переменной. Если тип переменной-массива соответствует типу массива в словаре, то, конечно, будет быстрее. Не нужно работать на варианте, если можно задать специальный тип.
Я подобный вопрос разбирал на задаче "СцепитьЕсли" — там, как раз нужно копить строки по каждому ключу.
Оптимальные варианты для подобных задач:
1. В качестве значения накапливать строку.
s = s & sep & i (Или dic(sKey) = dic(sKey) & sep & i ). Где i — Это очередной индекс вспомогательного одномерного строкового массива.
То есть, чтобы не тратить время на сцепку строк (они могут быть очень длинными), мы сцепляем индексы массива (указатели на эти строки в массиве, если угодно). Да — потом придётся прогнать ещё один цикл по каждой строке с индексами, чтобы их заменить на сами значения, то тесты показывали, что это заметно быстрее.
2. Вообще не хранить строки в качестве значений словаря.
Храним в словаре указатели (индексы массива) на строки в отдельном строковом массиве. Так и извлекать ничего не нужно будет. В этом массиве строки формируем по принципу из п.1 — с помощью ещё одного вспомогательного массива.
3. Отсортировать массив. Самый простой и быстрый вариант.
Отсортировать массив по ключам. В этом случае, у нас будет тольлко один буферный строковый массив — для каждого ключа по почереди. Кладём строки в этом массив и, после окончания очередного ключа, делаем редим и сцепляем.
Это сработает, если у вас есть сортер от bedvit'а. В противном случае, время сортировки вполне может быть больше времени вариантов 1 и 2. Более того, если вам потом нужно эти агрегированные строки всё-равно добавить в словарь (например, чтобы проставить их по ключам на листе), то добавление пар произойдёт заметно быстрее. .
Join строкового массива очень быстрый. Но было бы ещё быстрее, если бы была возможность задать индексы строк массива для сцепки — это бы позволило избежать ReDim Preserve и позволило бы вообще собрать все значения в один массив, в другом двумерном (Long) массиве (в том же цикле) запомнить индекс первого и последнего элемента по ключу и потом просто отдать в библу, чтобы "сделала красиво" (ил прогнать в цикле на стороне VBA).
Для подробного разбора вопроса агрегации строк по ключу я, когда-нибудь сделаю отдельную тему.
UPD: так же она
Изменено: - 02.06.2024 09:50:19
(Изменение названия Темы. Удаление эмоциональных сообщений)
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел)