Tôi đã viết một chút mã để tạo mảng đa chiều thay vì mảng mảng để tôi có thể lưu một số bộ nhớ. Sau đó, tôi chạy một số thử nghiệm để so sánh tốc độ của nó với mảng Java thông thường (int [] []) vì tôi không muốn chương trình của mình chạy chậm hơn ngay cả khi nó tiết kiệm bộ nhớ. Những gì tôi thấy trong các bài kiểm tra tính thời gian khiến tôi bối rối. Dưới đây là kết quả điển hình cho chạy thử nghiệm. Thời gian cho cùng một chút mã. Chú ý cách hai cái cuối cùng lớn hơn bốn cái đầu tiên.Tôi gặp vấn đề về hiệu năng Java mà tôi không hiểu
thời gian: 58.343.722 ns
thời gian: 59.451.156 ns
thời gian: 51.374.777 nsthời gian: 61.777.424 ns
thời gian: 813.156.695 ns
thời gian: 782.140.511 ns
Bây giờ Điều đầu tiên tôi nghĩ là bộ thu gom rác đang nổ. Tôi nâng giới hạn bộ nhớ lên 5GB (-Xmx5g) sao cho bộ thu gom rác chắc chắn Tôi không bắt đầu. Không có gì thay đổi. Tôi di chuyển mọi thứ xung quanh, nhưng mô hình vẫn ở lại.
Vậy mô hình là gì? Trong ba lần đầu tiên, bit mã nằm trong một hàm và tôi gọi nó ba lần. Trong lần thứ ba ba lần bit mã được lặp lại trong một hàm duy nhất ba lần. Vì vậy, các mô hình là bất cứ khi nào bit mã được chạy nhiều lần trong cùng một chức năng thời gian cần để chạy bit mã sẽ bắt đầu với bit thứ hai của mã và ở lại đó sau đó.
Tôi đã tìm thấy một sự thay đổi đó sẽ tạo ra kết quả như thế này:
thời gian: 58.729.424 ns
thời gian: 59.965.426 ns
thời gian: 51.441.618 nsthời gian: 57.359.741 ns
thời gian: 65362705 ns
thời gian: 857942387 ns
Những gì tôi đã làm là thêm một sự chậm trễ một phần nghìn giây giữa các bit mã của ba giây thứ hai. Làm điều đó chỉ tăng tốc độ thứ hai của các bit mã trong khối và không có lượng trễ sẽ tăng tốc bất kỳ bit mã nào sau đó.
Thẳng thắn, tôi bối rối. Tôi không thể giải thích hành vi này. Ai đó có thể làm sáng tỏ những gì đang xảy ra?
Đây là mã:
package multidimensionalarraytests;
import java.lang.reflect.Array;
import java.util.logging.Level;
import java.util.logging.Logger;
public class MultidimensionalArrayTests {
static ArrayInt2Dv1 array=new ArrayInt2Dv1(10000,10000);
public static void main(String[] args) {
System.out.println("ignore the warmup");
test();
test();
combined();
combined();
System.out.println("running tests");
test();
test();
test();
System.out.println();
combined();
}
static long test(){
int value=1;
long start,stop,time;
System.out.print("time: ");
start=System.nanoTime();
for(int x=0;x<array.length1;x++){
for(int y=0;y<array.length2;y++){
array.set(x, y, value);
value=array.get(x, y);
}
}
stop=System.nanoTime();
time=(stop-start);
System.out.println(time+" ns");
return time;
}
static void combined(){
int value=1;
long start,stop,time;
System.out.print("time: ");
start=System.nanoTime();
for(int x=0;x<array.length1;x++){
for(int y=0;y<array.length2;y++){
array.set(x, y, value);
value=array.get(x, y);
}
}
stop=System.nanoTime();
time=(stop-start);
System.out.println(time+" ns");
//try {Thread.sleep(1);} catch (InterruptedException ex) {}
System.out.print("time: ");
start=System.nanoTime();
for(int x=0;x<array.length1;x++){
for(int y=0;y<array.length2;y++){
array.set(x, y, value);
value=array.get(x, y);
}
}
stop=System.nanoTime();
time=(stop-start);
System.out.println(time+" ns");
//try {Thread.sleep(60000);} catch (InterruptedException ex) {}
System.out.print("time: ");
start=System.nanoTime();
for(int x=0;x<array.length1;x++){
for(int y=0;y<array.length2;y++){
array.set(x, y, value);
value=array.get(x, y);
}
}
stop=System.nanoTime();
time=(stop-start);
System.out.println(time+" ns");
}
}
và:
package multidimensionalarraytests;
public class ArrayInt2Dv1 {
int [] array;
public final int length1;
public final int length2;
public ArrayInt2Dv1(int length1, int length2){
this.length1=length1;
this.length2=length2;
array=new int[length1*length2];
}
public int get(int x,int y){
return array[x*length2+y];
}
public void set(int x,int y,int value){
array[x*length2+y]=value;
}
}
--- Chỉnh sửa ---
Kết quả trên Windows 7 với các tùy chọn -Xms5g -Xmx5g -XX: + PrintCompilation -verbose: gc -XX: CICompilerCount = 1 -Xbatch
time: 299 1 b multidimensionalarraytests.ArrayInt2Dv1::set (15 bytes)
302 2 b multidimensionalarraytests.ArrayInt2Dv1::get (14 bytes)
303 1 % b multidimensionalarraytests.MultidimensionalArrayTests::test @ 31 (114 bytes)
358 1 % multidimensionalarraytests.MultidimensionalArrayTests::test @ -2 (114 bytes) made not entrant
60671451 ns
359 3 b multidimensionalarraytests.MultidimensionalArrayTests::test (114 bytes)
time: 365 2 % b multidimensionalarraytests.MultidimensionalArrayTests::test @ 31 (114 bytes)
58104484 ns
time: 425 3 % b multidimensionalarraytests.MultidimensionalArrayTests::combined @ 31 (330 bytes)
69008251 ns
time: 806898159 ns
time: 845447596 ns
2146 4 b multidimensionalarraytests.MultidimensionalArrayTests::combined (330 bytes)
time: 52493169 ns
time: 804304528 ns
time: 845500191 ns
running tests
time: 51290771 ns
time: 51922285 ns
time: 51264108 ns
time: 52258679 ns
time: 842229025 ns
time: 871403625 ns
Trên Linux (Ubuntu trên VirtualBox trên cùng một máy) với các tùy chọn tương tự:
283 1 b java.lang.String::hashCode (60 bytes)
285 2 b sun.nio.cs.UTF_8$Encoder::encodeArrayLoop (490 bytes)
287 3 b java.lang.String::charAt (33 bytes)
287 4 b java.lang.String::indexOf (151 bytes)
297 5 b java.io.UnixFileSystem::normalize (75 bytes)
2850 6 b java.lang.String::lastIndexOf (156 bytes)
ignore the warmup
time: 5885 7 b multidimensionalarraytests.ArrayInt2Dv1::set (15 bytes)
5948 8 b multidimensionalarraytests.ArrayInt2Dv1::get (14 bytes)
5949 1% b multidimensionalarraytests.MultidimensionalArrayTests::test @ 31 (114 bytes)
11529998483 ns
17565 9 b multidimensionalarraytests.MultidimensionalArrayTests::test (114 bytes)
time: 1619622928 ns
time: 19718 2% b multidimensionalarraytests.MultidimensionalArrayTests::combined @ 31 (330 bytes)
475786382 ns
time: 288586857 ns
time: 315560700 ns
20789 10 b multidimensionalarraytests.MultidimensionalArrayTests::combined (330 bytes)
time: 460577230 ns
time: 311525066 ns
time: 312343429 ns
running tests
time: 310261854 ns
time: 298826592 ns
time: 304689920 ns
time: 315416579 ns
time: 299473245 ns
time: 290211350 ns
Để bắt đầu, hãy xem http://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java – NPE
Lời khuyên tốt. Tôi đã thay đổi mã trên để phản ánh các khuyến nghị và chạy chương trình với các tùy chọn: -Xms5g -Xmx5g -XX: + PrintCompilation -verbose: gc -XX: CICompilerCount = 1 -Xbatch. Nó đã không thay đổi đáng kể kết quả mặc dù. – user1145922
Tôi đã thử (với mã được cập nhật) và tôi không thể tạo lại hiệu ứng bằng cách sử dụng Java 6u26 trên Ubuntu 64 bit. Ở đây, tất cả sáu lần trôi qua đều nằm trong khoảng 10% của nhau (thời gian khởi động biến động do trình biên dịch vừa mới khởi động). – NPE