Ответ: это сложно.
Реализация по умолчанию неизменяемого набора: scala.collection.immutable.Set . Это имеет особых случаев для размеров от 1 до 4. Как только у вас будет более 4 элементов, он будет использовать scala.collection.immutable.HashSet .
Очень маленький с (1..4)
Допустим, у вас есть большой набор b
и небольшой набор s
, где s
содержит <4 элемента. </p>
Тогда получится большая разница:
b & s
отфильтрует все элементы b
от членства в s
и, следовательно, выполнит сравнение равенств b.count * s.count. Поскольку b большое, это будет довольно медленно.
s & b
отфильтрует несколько элементов s
по отношению к членству в b
, которое равно s.length, кратному хэшированию и сравнению на равенство, если хэши совпадают (помните, что b - это HashSet). Поскольку он маленький, он должен быть очень быстрым.
Маленький s (n> 4)
Как только s
будет больше, чем 4 элемента, он также станет HashSet. Пересечение для HashSets написано симметрично и очень эффективно. Он объединит древовидные структуры s
и b
и выполнит сравнение на равенство при совпадении хэшей. Будет использовано максимальное структурное разделение. Например. если b
содержит все элементы s
, результатом будет тот же экземпляр , что и s, поэтому объекты не будут выделяться.
Общие советы
Если вы просто пишете универсальный код, в котором вас мало заботит высокая производительность, можно использовать реализации по умолчанию, такие как scala.collection.Set
. Однако, если вы заботитесь о характеристиках производительности, предпочтительнее использовать конкретную реализацию. Например. если s
и b
объявлены как scala.collection.immutable.HashSet
, вы получите стабильно высокую производительность независимо от порядка при условии, что у вас есть хорошая хеш-функция.