2012-05-24 32 views
23

benchmark nhỏ của tôi:Nhân thời gian trong BigInteger

import java.math.*; 
import java.util.*; 
import java.io.*; 
public class c 
{ 
    static Random rnd = new Random(); 
    public static String addDigits(String a, int n) 
    { 
     if(a==null) return null; 
     if(n<=0) return a; 
     for(int i=0; i<n; i++) 
      a+=rnd.nextInt(10); 
     return a; 
    } 
    public static void main(String[] args) throws IOException 
    { 
     int n = 10000; \\number of iterations 
     int k = 10; \\number of digits added at each iteration 

     BigInteger a; 
     BigInteger b; 

     String as = ""; 
     String bs = ""; 
     as += rnd.nextInt(9)+1; 
     bs += rnd.nextInt(9)+1; 
     a = new BigInteger(as); 
     b = new BigInteger(bs); 
     FileWriter fw = new FileWriter("c.txt"); 
     long t1 = System.nanoTime(); 
     a.multiply(b); 
     long t2 = System.nanoTime(); 
     //fw.write("1,"+(t2-t1)+"\n"); 
     if(k>0) { 
      as = addDigits(as, k-1); 
      bs = addDigits(as, k-1); 
     } 
     for(int i=0; i<n; i++) 
     { 
      a = new BigInteger(as); 
      b = new BigInteger(bs); 
      t1 = System.nanoTime(); 
      a.multiply(b); 
      t2 = System.nanoTime(); 
      fw.write(((i+1)*k)+","+(t2-t1)+"\n"); 
      if(i < n-1) 
      { 
       as = addDigits(as, k); 
       bs = addDigits(as, k); 
      } 
      System.out.println((i+1)*k); 
     }  

     fw.close(); 
    } 
} 

Nó đo thời gian nhân của n chữ số BigInteger

Kết quả: enter image description here

Bạn có thể dễ dàng nhận thấy xu hướng này nhưng tại sao có quá tiếng ồn lớn trên 50000 chữ số? Đó là do bộ thu gom rác hoặc có điều gì khác ảnh hưởng đến kết quả của tôi không? Khi thực hiện kiểm tra, không có ứng dụng nào khác đang chạy.

Kết quả từ thử nghiệm chỉ với các chữ số lẻ. Xét nghiệm này là ngắn hơn (n = 1000, k = 100)

enter image description here

chữ số Odd (n = 10000, k = 10) enter image description here

Như bạn có thể thấy có một tiếng động rất lớn giữa 65000 và 70000 tôi tự hỏi tại sao ...

chữ số Odd (n = 10000, k = 10), System.gc() mỗi 1000 lần lặp enter image description here Kết quả trong tiếng ồn giữa 50000-70000

+3

Không có cách nào để biết thông tin bạn đã hiển thị. Tại sao bạn không thử 'System.gc()' cứ lặp lại 500-1000 để xem nó có làm mịn nó không. – hvgotcodes

+0

"Không có ứng dụng nào khác đang chạy". Bạn có đang ở trong môi trường máy tính thời gian thực không có hệ điều hành chia sẻ thời gian (như Windows) không? Không thể đảm bảo mọi chu kỳ CPU chỉ được cấp phát cho ứng dụng của bạn. – mellamokb

+1

Sry để thoát khỏi chủ đề nhưng, bạn đang vẽ chương trình gì? – keyser

Trả lời

9

Tôi cũng nghi ngờ đây là hiệu ứng hâm nóng JVM. Không khởi động liên quan đến việc nạp lớp hoặc trình biên dịch JIT, mà là sự khởi động của heap.

Đặt vòng lặp (java) quanh toàn bộ điểm chuẩn và chạy nó một số lần. (Nếu đây cung cấp cho bạn các đồ thị tương tự như trước ... bạn sẽ có bằng chứng rằng đây không phải là một hiệu ứng hâm lại. Hiện tại bạn không có bất kỳ kinh nghiệm bằng chứng một cách này hay cách khác.)


Một khả năng khác là tiếng ồn là do tương tác của điểm chuẩn của bạn với hệ điều hành và/hoặc các nội dung khác đang chạy trên máy.

  • Bạn đang ghi dữ liệu thời gian của mình vào luồng không được lọc. Điều đó có nghĩa LOTS của syscalls, và (tiềm năng) rất nhiều đĩa hạt mịn viết.
  • Bạn đang thực hiện rất nhiều cuộc gọi đến nanoTime() và rằng có thể giới thiệu tiếng ồn.
  • Nếu có thứ khác đang chạy trên máy của bạn (ví dụ: bạn đang duyệt web) sẽ làm chậm điểm chuẩn của bạn một chút và giới thiệu tiếng ồn.
  • Có thể có sự cạnh tranh về bộ nhớ vật lý ... nếu bạn có quá nhiều hoạt động trên máy tính của bạn cho số lượng RAM.

Cuối cùng, một số tiền nhất định của tiếng ồn là không thể tránh khỏi, bởi vì mỗi người trong số những multiply cuộc gọi tạo ra rác, và các bộ thu rác sẽ cần phải làm việc để đối phó với nó.


Cuối cùng cuối cùng, nếu bạn tự chạy thu gom rác (hoặc tăng kích thước heap) để "mịn ra" các điểm dữ liệu, những gì bạn đang thực sự làm là che giấu một trong những chi phí của multiply cuộc gọi. Các biểu đồ kết quả trông đẹp, nhưng nó gây hiểu lầm:

  • Sự ồn ào phản ánh điều gì sẽ xảy ra trong cuộc sống thực.
  • Chi phí thực sự của multiply thực sự bao gồm chi phí khấu hao của việc chạy GC để xử lý rác thải do cuộc gọi tạo ra.

Để có được một phép đo phản ánh cách mà BigInteger cư xử trong cuộc sống thực, bạn cần phải chạy thử nghiệm một số lượng lớn các lần, tính thời gian trung bình và phù hợp với một đường cong với dữ liệu điểm trung bình.

Hãy nhớ rằng, mục đích thực sự của trò chơi là để có được kết quả khoa học hợp lệ ... không phải là một đường cong trơn tru.

3

Nếu bạn làm một microbenchmark, bạn phải "khởi động" JVM đầu tiên để cho JIT tối ưu hóa mã, và sau đó bạn có thể đo lường hiệu suất. Nếu không, bạn đang đo công việc được thực hiện bởi JIT và có thể thay đổi kết quả trên mỗi lần chạy.

"nhiễu" xảy ra có thể do bộ nhớ cache của CPU bị vượt quá và hiệu suất bắt đầu giảm xuống.

+1

OK, nhưng trường hợp JVM không được khởi động lại là lúc bắt đầu mô phỏng. Sau đó, chúng ta có thể giả sử trạng thái ấm lên. Nhưng tiếng ồn ở cuối mô phỏng, không phải lúc đầu –

Các vấn đề liên quan