Skip to content

Commit 9f04253

Browse files
authored
Collect with initial capacity (#1350)
We now have collecting functions with initial capacity as a performance hint. Addresses #1309.
1 parent db29962 commit 9f04253

3 files changed

Lines changed: 40 additions & 9 deletions

File tree

libraries/common/array.effekt

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -677,18 +677,27 @@ def feed[T, R](array: Array[T]) { reader: () => R / read[T] }: R = {
677677
}
678678
}
679679

680+
/// Collects elements emitted by a push stream producer `stream` into a new array,
681+
/// discarding the result of the producer.
682+
/// The provided capacity is a hint for the expected number of elements.
683+
/// It must be strictly larger than zero.
684+
def collect[A](capacity: Int) { stream: () => Unit / emit[A] }: Array[A] =
685+
returning::collect[A, Unit](capacity){stream}.second
686+
680687
/// Collects elements emitted by a push stream producer `stream` into a new array,
681688
/// discarding the result of the producer.
682689
def collect[A] { stream: () => Unit / emit[A] }: Array[A] =
683-
returning::collect[A, Unit]{stream}.second
690+
collect[A](4){stream}
684691

685692
namespace returning {
686693

687694
/// Collects elements emitted by a push stream producer `stream` into a new array,
688695
/// returning the result of the producer as well as the collected array.
689-
def collect[A, R] { stream: () => R / emit[A] }: (R, Array[A]) = {
696+
/// The provided capacity is a hint for the expected number of elements.
697+
/// It must be strictly larger than zero.
698+
def collect[A, R](capacity: Int) { stream: () => R / emit[A] }: (R, Array[A]) = {
690699
var i = 0
691-
var a = unsafeAllocate(1)
700+
var a = unsafeAllocate(capacity)
692701
try {
693702
(stream(), a.resize(i))
694703
} with emit[A] { (v) =>
@@ -698,4 +707,10 @@ namespace returning {
698707
resume(())
699708
}
700709
}
710+
711+
/// Collects elements emitted by a push stream producer `stream` into a new array,
712+
/// returning the result of the producer as well as the collected array.
713+
def collect[A, R] { stream: () => R / emit[A] }: (R, Array[A]) =
714+
returning::collect[A, R](4){stream}
715+
701716
}

libraries/common/bytearray.effekt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -300,13 +300,17 @@ def feed[R](bytes: ByteArray) { reader: () => R / read[Byte] }: R = {
300300
}
301301
}
302302

303+
def collect(capacity: Int) { stream: () => Unit / emit[Byte] }: ByteArray =
304+
returning::collect[Unit](capacity){stream}.second
305+
303306
def collect { stream: () => Unit / emit[Byte] }: ByteArray =
304-
returning::collect[Unit]{stream}.second
307+
collect(4){stream}
305308

306309
namespace returning {
307-
def collect[R] { stream: () => R / emit[Byte] }: (R, ByteArray) = {
310+
311+
def collect[R](capacity: Int) { stream: () => R / emit[Byte] }: (R, ByteArray) = {
308312
var i = 0
309-
var a = allocate(1)
313+
var a = allocate(capacity)
310314
try {
311315
(stream(), a.resize(i))
312316
} with emit[Byte] { (v) =>
@@ -316,4 +320,8 @@ namespace returning {
316320
resume(())
317321
}
318322
}
323+
324+
def collect[R] { stream: () => R / emit[Byte] }: (R, ByteArray) =
325+
returning::collect(4){stream}
326+
319327
}

libraries/common/string.effekt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,12 +251,20 @@ def each(string: String): Unit / emit[Char] =
251251
}
252252
}
253253

254+
def collect(capacity: Int) { stream: () => Unit / emit[Char] }: String =
255+
returning::collect[Unit](capacity){stream}.second
256+
254257
def collect { stream: () => Unit / emit[Char] }: String =
255-
returning::collect[Unit]{stream}.second
258+
collect(4){stream}
256259

257260
namespace returning {
258-
def collect[R] { stream: () => R / emit[Char] }: (R, String) = {
259-
val (result, bytes) = bytearray::returning::collect[R] { encodeUTF8 { stream } }
261+
262+
def collect[R](capacity: Int) { stream: () => R / emit[Char] }: (R, String) = {
263+
val (result, bytes) = bytearray::returning::collect[R](capacity) { encodeUTF8 { stream } }
260264
(result, bytes.toString)
261265
}
266+
267+
def collect[R] { stream: () => R / emit[Char] }: (R, String) =
268+
returning::collect(4){stream}
269+
262270
}

0 commit comments

Comments
 (0)