Разница между размером и размером

В чем смысловая разница между size а также sizeIs? Например,

List(1,2,3).sizeIs > 1 // true
List(1,2,3).size > 1   // true

Луис упоминает в комментарии, что

... на 2.13+ можно использовать sizeIs > 1 который будет более эффективным, чем size > 1 поскольку первый не вычисляет весь размер перед возвратом

Добавление методов сравнения размеров в IterableOps #6950, по-видимому, является запросом извлечения, который его представил.

Чтение скаладока

Возвращает класс значений, содержащий операции для сравнения размера этого $coll с тестовым значением. Эти операции осуществляются с точки зрения sizeCompare(Int)

мне не понятно почему sizeIs более эффективный, чем обычный size?

1 ответ

Насколько я понимаю изменения.

Идея в том, что для коллекций, у которых нет O(1) (константа) size. Потом,sizeIsможет быть более эффективным, особенно для сравнений с небольшими значениями (например, 1 в комментарии).

Но почему?
Просто потому, что вместо вычисления всего размера и последующего сравненияsizeIsвозвращает объект, который при вычислении сравнения может вернуться раньше.
Например, давайте проверим код

def sizeCompare(otherSize: Int): Int = {
  if (otherSize < 0) 1
  else {
    val known = knownSize
    if (known >= 0) Integer.compare(known, otherSize)
    else {
      var i = 0
      val it = iterator
      while (it.hasNext) {
        if (i == otherSize) return if (it.hasNext) 1 else 0 // HERE!!! - return as fast as possible.
        it.next()
        i += 1
      }
      i - otherSize
    }
  }
}

Таким образом, в примере с комментарием предположим, что очень-очень длинный список из трех элементов.sizeIs > 1вернется, как только узнает, что в списке есть хотя бы один элемент иhasMore. Таким образом, экономия затрат на обход двух других элементов для вычисления размера 3 и последующего сравнения.

Обратите внимание: если размер коллекции больше, чем значение для сравнения, то производительность будет примерно такой же (возможно, медленнее, чем простоsizeиз-за дополнительных сравнений на каждом цикле). Таким образом, я бы рекомендовал это только для сравнений с небольшими значениями или когда вы считаете, что значения будут меньше, чем коллекция.

Другие вопросы по тегам