jimn
01/08/2020, 12:21 PMval stepsize = piv.size() / Runtime.getRuntime().availableProcessors()
(0 until piv.size() ) .step( stepsize).map {
it until minOf(piv.size(),it+stepsize)
}
is there an easier way of getting chunked IntRange sequences ?Eduardo Pinto
01/08/2020, 12:22 PMjimn
01/08/2020, 12:22 PMEduardo Pinto
01/08/2020, 12:23 PMEduardo Pinto
01/08/2020, 12:24 PMjimn
01/08/2020, 12:27 PMjimn
01/08/2020, 12:39 PMsequence {
for (first in 0 until piv.size() step stepsize) {
yield(async {
for (iy in first until minOf(piv.size(), first + stepsize)) {
{block}
} }) } }
Joffrey
01/08/2020, 3:06 PMSequence<IntRange>
, why not:
fun IntRange.subRanges(chunkSize: Int) = sequence {
for (i in this@subRanges step chunkSize) {
yield(i until minOf(last, i + chunkSize))
}
}
You may then use it this way to get your sequence:
val stepsize = piv.size() / Runtime.getRuntime().availableProcessors()
(0 until piv.size()).subRanges(stepSize)
I believe it shows better what you’re doing in the business code, rather than mixing the index calculations with the business.jimn
01/08/2020, 3:42 PMjimn
01/08/2020, 3:44 PMJoffrey
01/08/2020, 3:44 PMJoffrey
01/08/2020, 3:46 PMIntRange
was iterable and therefore already had a chunked
method, I’ll rename it to avoid confusion.jimn
01/08/2020, 3:47 PMJoffrey
01/08/2020, 3:56 PMfun IntRange.split(nSubRanges: Int) = sequence {
val subSize = (last - first) / nSubRanges
for (i in this@split step subSize) {
yield(i..minOf(last, i + subSize - 1))
}
}
I haven’t tested that, there may be off by one errors 🙂 but at least it encapsulates the initial division as welljimn
01/08/2020, 3:58 PMJoffrey
01/08/2020, 4:04 PMlast
from the this
range requires me to use ..
otherwise you don’t get the very last valuejimn
01/08/2020, 4:26 PMlast
is my piv.size() or it--
yield(i..minOf(last, i + subSize - 1)) (edit: woops!)
so reading the IntRange source really just deepens the distrust a bit by explaining "last" is clearly /just/ public val last: Int = getProgressionLastElement(start.toInt(), endInclusive.toInt(), step).toInt()
jimn
01/08/2020, 4:28 PMyield(i until minOf(last, i + chunkSize))
floats its definitely preferable of the two.jimn
01/08/2020, 4:33 PMi.. (min(...)/*=last*/)
would be overflow.jimn
01/08/2020, 4:36 PMuntil (i + chunkSize)
and i..(i + chunkSize-1)
are equal and with the above, statement, we can drop the -1 formjimn
01/08/2020, 4:39 PMfun IntRange.subRanges(chunkSize: Int) = sequence {
for (i in this@subRanges step chunkSize) {
yield(i until minOf(last, i + chunkSize)) }}
wins the beauty pagent. will live next to typealias Vect0r<T>=Pai2/*interface pair tuple*/<()->Int,(Int)->T>
jimn
01/08/2020, 5:23 PMinfix operator fun IntRange.div(denominator: Int): Vect0r<IntRange> = (this to last / denominator).let { (intRange, step) ->
Vect0r(denominator.`⟲`) { x: Int -> assert(denominator > x, "$x index greater of $denominator".`⟲`)
(step * x) until Math.min(intRange.last, x+step) } }
fun IntRange.subRanges(chunkSize: Int=this.step) =
let { sequence { for (i in it step chunkSize) yield(i until minOf(last, i + chunkSize)) } }
Joffrey
01/12/2020, 1:17 PMendinclusive is in fact piv.size() soThis has to be wrong. Last must be the last element of the range, not the size.would be overflow.i.. (min(...)/*=last*/)
first..last
should be the complete range.
val r = 5..12
println(r.last) // 12
val arr = arrayOf(1, 2, 3)
println(arr.indices.last) // 2
// prints the last index, not size
jimn
01/14/2020, 4:34 PMjimn
01/14/2020, 6:41 PMfun IntRange.split(nSubRanges: Int) = run {
val i1 = this.count()
val subSize = i1 / nSubRanges
sequence {
for (i in this@split step subSize) {
yield(i..minOf(last, i + subSize - 1))
}
}
}
this seems to reflect nSubranges more accuratelyjimn
01/14/2020, 6:49 PMjimn
01/14/2020, 6:58 PMfun IntRange.split(nSubRanges: Int) = run {
val subSize = (last - first +(1- first)) / nSubRanges
sequence {
for (i in this@split step subSize) {
yield(i..minOf(last, i + subSize - 1)) } } }
this definitely bears testing outside of my immediate usecases for which it seems to work.