2017-08-01 178 views
2

說數組初始化,我有以下的功能,讓我創建矩陣:多線程在科特林

inline fun <reified T> Matrix2D(w: Int, h: Int, init: (Int, Int) -> T) = 
    Array(w){ x -> Array(h){ y -> init(x, y) } } 

inline fun <reified T> Matrix2D(w: Int, h: Int, value: T) = 
    Array(w){ Array(h){ value } } 

// For example: 
val m = Matrix2D(400, 400) { x, y -> 
    Color(x.toDouble()/400.0, y.toDouble()/400.0, 0.0) 
} 

我也不想允許爲空,因爲它的將是一個痛苦的稍後處理元素訪問。

如何使用多線程/協程來初始化這樣的矩陣,其中每個線程初始化矩陣的自己的矩形,而不允許矩陣單元的可空性?

回答

1

是的,你可以創建並行Matrix2D,例如:

val threads = Matrix2D(10, 3){x, y-> Thread.currentThread() }.flatten().distinct() 

//    v--- size > 1 
println(threads.size) 

inline fun <reified T> Matrix2D(w: Int, h: Int, crossinline init: (Int, Int) -> T)= 
     //      v--- create array in parallel 
     generatorOf(w){x -> Array(h) {y -> init(x, y) } }.map{ it() }.toTypedArray() 
     //       get the final result `Matrix2D` ---^ 

//      v--- create array generator 
inline fun <reified T> generatorOf(size: Int, crossinline init:(Int) -> T) = 
    //v--- you can use `ForkJoinPool#commonPool`, but it will run task in work thread 
    ForkJoinPool(20).let { 
     Array(size) { i -> it.submit(Callable { init(i) }).let { { it.get() } } } 
     //     return the lambda generator()->T ---^ 
    } 

你也可以寫一個擴展功能toArray去除中間map操作&提升性能,例如:

inline fun <reified T> Matrix2D(w: Int, h: Int, crossinline init: (Int, Int) -> T)= 
     //       v--- init array elements in parallel 
     generatorOf(w) { x -> Array(h) { y -> init(x, y) } }.toArray{it()} 
     //   transform to the `Matrix2D` directly ---^ 

//        v--- convert Array<T> to Array<R> 
inline fun <T,reified R> Array<T>.toArray(transform:(T)->R):Array<R>{ 
    return Array(size){i->transform(get(i))} 
} 

爲什麼做了外部數組初始化的Matrix2D啓動線程,你可以看到sum two double[][] with parallel stream更進一步。