Powershell Hashtable с начальной емкостью - PullRequest
0 голосов
/ 15 ноября 2018

Мне было интересно, как вы объявляете хеш-таблицу в powershell с начальной емкостью.Я знаю, насколько большим он должен быть, но я должен присвоить ему значения в цикле.

Так что-то вроде:

$hashtable = @{} (100)

1 Ответ

0 голосов
/ 15 ноября 2018

JeroenMostert хорошо объясняет, почему вам не может понадобиться для указания начальной емкости:

Имейте в виду, что предварительное указание емкости обычно мало что дает в плане памяти или времени выполнения; он уже реализует щедрое динамическое определение размера, и если ваше предположение неверно, преимущества в основном испаряются.

Если вам нужно , укажите начальную емкость :

Кончик шляпы PetSerAl за помощь.

Поскольку хеш-таблицы PowerShell всегда не чувствительны к регистру в отношении поиска ключей, [hashtable]::new(100) не не работает, к сожалению, потому что по умолчанию создается регистр - чувствительный хеш-таблица.

Поэтому необходимо использовать перегрузку конструктора [System.Collections.Hashtable], которая позволяет указывать метод сравнения на равенство ключей, чтобы вы могли указать чувствительный к культуре компаратор равенства без учета регистра для соответствия обычному PowerShell поведение хеш-таблицы [1] :

# PSv5+ syntax
$hashtable = [hashtable]::new(100, [StringComparer]::CurrentCultureIgnoreCase)

# PSv4- syntax
$hashtable = New-Object hashtable 100, ([StringComparer]::CurrentCultureIgnoreCase)

PetSerAl предлагает следующую альтернативу:

$hashtable = [System.Collections.Specialized.CollectionsUtil]::CreateCaseInsensitiveHashtable(100)

Кроме того, как указывает PetSerAl, PowerShell кэширует средство сравнения равенства ключей для текущего сеанса - поэтому изменение текущей культуры в сеансе игнорируется . Если вы хотите эмулировать это сомнительное поведение, PetSerAl предоставляет следующую команду:

$hashtable = [hashtable]::new(100,
 [hashtable].GetProperty(
   'EqualityComparer',
   [System.Reflection.BindingFlags]'NonPublic, Instance'
 ).GetValue(@{}))

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


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

С документы (выделение добавлено):

Хеш-таблица Емкость используется для расчета оптимального количества сегментов хеш-таблицы на основе коэффициента загрузки. Емкость автоматически увеличивается при необходимости.

Коэффициент нагрузки - это максимальное соотношение элементов к корзинам. Меньший коэффициент загрузки означает более быстрый поиск за счет увеличения потребления памяти.

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


[1] Обратите внимание, что во многих контекстах PowerShell использует инвариантную культуру для строковых операций, но хеш-таблицы кажутся исключением - см. эту проблему GitHub и этот ответ .
Исходный код раскрывает использование CurrentCultureIgnoreCase в конструкторе хеш-таблиц PowerShell.

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