Powershell Hashtable с начальной емкостью
Мне было интересно, как вы объявляете хеш-таблицу в powershell с начальной емкостью. Я знаю, насколько большим я хочу, чтобы он был, но я должен присвоить ему значения в цикле.
Так что-то вроде:
$hashtable = @{} (100)
1 ответ
Jeroen Mostert хорошо объясняет, почему вам не нужно указывать начальную емкость:
Имейте в виду, что предварительное указание емкости обычно не выигрывает вас с точки зрения памяти или времени выполнения; он уже реализует щедрое динамическое определение размера, и если ваше предположение не верное, преимущества в основном испаряются.
Если вам нужно указать начальную емкость:
Кончик шляпы 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.