私はRustをよく経験しておらず、パフォーマンスの問題を診断しようとしています。下にはかなり速いJavaコード(7秒で実行)があり、これと同等のRustコードが必要です。しかし、錆のコードは非常にゆっくり実行されます(はい、私は--release
でコンパイルしました)、またオーバーフローするようです。 i32
からi64
に変更すると、あとでオーバーフローがプッシュされますが、それでも問題は発生します。私が書いたものにはいくつかのバグがあると思われますが、長い間問題を見つめた後、私は助けを求めることにしました。パフォーマンスの問題を診断する
public class Blah {
static final int N = 100;
static final int K = 50;
public static void main(String[] args) {
//initialize S
int[] S = new int[N];
for (int n = 1; n <= N; n++) S[n-1] = n*n;
// compute maxsum and minsum
int maxsum = 0;
int minsum = 0;
for (int n = 0; n < K; n++) {
minsum += S[n];
maxsum += S[N-n-1];
}
// initialize x and y
int[][] x = new int[K+1][maxsum+1];
int[][] y = new int[K+1][maxsum+1];
y[0][0] = 1;
// bottom-up DP over n
for (int n = 1; n <= N; n++) {
x[0][0] = 1;
for (int k = 1; k <= K; k++) {
int e = S[n-1];
for (int s = 0; s < e; s++) x[k][s] = y[k][s];
for (int s = 0; s <= maxsum-e; s++) {
x[k][s+e] = y[k-1][s] + y[k][s+e];
}
}
int[][] t = x;
x = y;
y = t;
}
// sum of unique K-subset sums
int sum = 0;
for (int s = minsum; s <= maxsum; s++) {
if (y[K][s] == 1) sum += s;
}
System.out.println(sum);
}
}
extern crate ndarray;
use ndarray::prelude::*;
use std::mem;
fn main() {
let numbers: Vec<i32> = (1..101).map(|x| x * x).collect();
let deg: usize = 50;
let mut min_sum: usize = 0;
for i in 0..deg {
min_sum += numbers[i] as usize;
}
let mut max_sum: usize = 0;
for i in deg..numbers.len() {
max_sum += numbers[i] as usize;
}
// Make an array
let mut x = OwnedArray::from_elem((deg + 1, max_sum + 1), 0i32);
let mut y = OwnedArray::from_elem((deg + 1, max_sum + 1), 0i32);
y[(0, 0)] = 1;
for n in 1..numbers.len() + 1 {
x[(0, 0)] = 1;
println!("Completed step {} out of {}", n, numbers.len());
for k in 1..deg + 1 {
let e = numbers[n - 1] as usize;
for s in 0..e {
x[(k, s)] = y[(k, s)];
}
for s in 0..max_sum - e + 1 {
x[(k, s + e)] = y[(k - 1, s)] + y[(k, s + e)];
}
}
mem::swap(&mut x, &mut y);
}
let mut ans = 0;
for s in min_sum..max_sum + 1 {
if y[(deg, s)] == 1 {
ans += s;
}
}
println!("{}", ans);
}
1)は、これは約7秒で実行しますが、よろしいですか?私のマシンでは、これは2秒未満で実行されます。 2)ここでオーバーフローする可能性はありません.2次元配列yの値を2次元配列yに代入しています.2次元配列yは0でいっぱいで、決して更新されません。結果として、2D配列xは0だけですあなたはここで何をしようとしていますか?私はオーバーフローを見ません.. –
@MostafaAli 1)私はあなたに何を伝えることができます、私は古いコンピュータを持っています。 Javaプログラムの7秒間は、Rustプログラムの完了に数分かかります。 2)オーバーフローについて。最終的な答えは2^31 - 1 = 2147483647より小さい〜10^8です。最後に、ゼロについて間違っています。 xとyはすべてゼロではありません。 –
申し訳ありませんが、私は合計を計算するコードの下部を見逃しました...いくつかの異なるロジックで終わった。 –