``` val stepsize = piv.size() / Runt...
# announcements
j
Copy code
val 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 ?
j
last i checked that's no sequnce
e
I miss the sequence word.
j
my intranges are in the millions. all the options use List<T>. my solution uses a List<T> as well, but my cpu count is not in the millions 
for-loops ftw i guess.
Copy code
sequence {
                    for (first in 0 until piv.size() step stepsize) {
                        yield(async {
                            for (iy in first until minOf(piv.size(), first + stepsize)) {
                                {block}
                            } }) } }
j
If what you’re looking for is a
Sequence<IntRange>
, why not:
Copy code
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:
Copy code
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.
j
there are 2.8 million ints to allocate, fill, and iterate for the unit test. these rows contain 9800 columns each
oh i see extension function, nicely done.
j
I don’t see how this makes any difference, there is only as many `IntRange`s as available processors created here, the `IntRange`s don’t contain all millions of integers, just the bounds.
Ah yes I didn’t realize
IntRange
was iterable and therefore already had a
chunked
method, I’ll rename it to avoid confusion.
j
i read your two seperate stanzas of code as two unrelated topics, particularly the ned sentence looks like an argument for code clarity over sequences until i noticed /chunked is your extension sequence.
👍 2
j
Maybe this would be even better for your use case:
Copy code
fun 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 well
j
.. has a track record of off by one for me. that said, "until size" is the best thing i've seen in my career after getting acclimated.
j
Using
last
from the
this
range requires me to use
..
otherwise you don’t get the very last value
j
this gives me some distrust for whether
last
is my piv.size() or it--
Copy code
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()
if
yield(i until minOf(last, i + chunkSize))
floats its definitely preferable of the two.
endinclusive is in fact piv.size() so
i.. (min(...)/*=last*/)
would be overflow.
i think this is a proof that
until (i + chunkSize)
and
i..(i + chunkSize-1)
are equal and with the above, statement, we can drop the -1 form
Copy code
fun 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>
Copy code
infix 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)) } }
j
endinclusive is in fact piv.size() so
i.. (min(...)/*=last*/)
would be overflow.
This has to be wrong. Last must be the last element of the range, not the size.
first..last
should be the complete range.
Copy code
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
Copy code
fun 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 accurately
count() is cheap for collections but IntRange is no colllection. 😞
Copy code
fun 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.