Skip to content

Commit

Permalink
Avoid :: and Integer allocation in API hashing
Browse files Browse the repository at this point in the history
  • Loading branch information
retronym committed Apr 27, 2020
1 parent 0fcb33d commit 59d1848
Showing 1 changed file with 18 additions and 5 deletions.
23 changes: 18 additions & 5 deletions internal/zinc-apiinfo/src/main/scala/xsbt/api/HashAPI.scala
Original file line number Diff line number Diff line change
Expand Up @@ -145,13 +145,26 @@ final class HashAPI private (
}
final def hashSymmetric[T](ts: TraversableOnce[T], hashF: T => Unit): Unit = {
val current = hash
val hashes = ts.toList.map { t =>
hash = 1
hashF(t)
finalizeHash
val hashIterable: IterableOnce[Any] = ts match {
case ts: collection.Iterable[T] =>
// Avoid creation of a temporary collection and avoid boxing of hashCodes by passing
// this iterator to `unorderedHash`. It returns itself each time with a different hashCode.
class HashIterator(delegate: Iterator[T]) extends Iterator[AnyRef] {
override def hasNext: Boolean = delegate.hasNext
def next(): AnyRef = { hash = 1; hashF(delegate.next()); this }
override def hashCode: Int = finalizeHash
}
new HashIterator(ts.iterator)
case _ =>
ts.toList.map { t =>
hash = 1
hashF(t)
finalizeHash
}
}
val tsHash = unorderedHash(hashIterable)
hash = current
extend(unorderedHash(hashes))
extend(tsHash)
}

@inline final def extend(a: Hash): Unit = {
Expand Down

0 comments on commit 59d1848

Please sign in to comment.