oge*_*gen 4 java arrays math scala
我是Scala的新手,我想用相同的性能级别翻译我的Java代码.
给定n个浮点向量和一个附加向量,我必须计算所有n个点的乘积并获得最大值.
使用Java对我来说非常简单
public static void main(String[] args) {
int N = 5000000;
int R = 200;
float[][] t = new float[N][R];
float[] u = new float[R];
Random r = new Random();
for (int i = 0;i<N;i++) {
for (int j = 0;j<R;j++) {
if (i == 0) {
u[j] = r.nextFloat();
}
t[i][j] = r.nextFloat();
}
}
long ts = System.currentTimeMillis();
float maxScore = -1.0f;
for (int i = 0;i < N;i++) {
float score = 0.0f;
for (int j = 0; i < R;i++) {
score += u[j] * t[i][j];
}
if (score > maxScore) {
maxScore = score;
}
}
System.out.println(System.currentTimeMillis() - ts);
System.out.println(maxScore);
}
Run Code Online (Sandbox Code Playgroud)
我的机器上的计算时间是6毫秒.
现在我必须使用Scala
val t = Array.ofDim[Float](N,R)
val u = Array.ofDim[Float](R)
// Filling with random floats like in Java
val ts = System.currentTimeMillis()
var maxScore: Float = -1.0f
for ( i <- 0 until N) {
var score = 0.0f
for (j <- 0 until R) {
score += u(j) * t(i)(j)
}
if (score > maxScore) {
maxScore = score
}
}
println(System.currentTimeMillis() - ts)
println(maxScore);
Run Code Online (Sandbox Code Playgroud)
上面的代码在我的机器上花了不止一秒.我的想法是Scala没有原始数组结构,例如Java中的float [],并且被集合替换.索引i的访问速度似乎比Java中的原始数组慢.
以下代码甚至更慢:
val maxScore = t.map( r => r zip u map Function.tupled(_*_) reduceLeft (_+_)).max
Run Code Online (Sandbox Code Playgroud)
需要26秒
我应该如何有效地迭代我的2个数组来计算它?
非常感谢
Tza*_*har 22
好吧,抱歉地说,但这里的奇怪的是你的Java实现有多快,你的斯卡拉一个并不怎么慢是- (!)遍历10十亿个细胞6ms的听起来好得是真实的-事实上- 你有一个错字在使这段代码更少的Java实现:
而不是for (int j = 0; j < R;j++),你有for (int j = 0; i < R;i++)- 这使内循环只运行200次而不是10亿 ...
如果你解决这个问题 - Scala和Java的性能是可比的.
这,BTW,实际上是Scala 的优势 - 它更难for (j <- 0 until R)出错:)