2013-09-16 38 views
6

Hôm nay tôi đã thực hiện một thử nghiệm đơn giản để so sánh tốc độ giữa java và c - một vòng lặp đơn giản làm cho số nguyên "i" tăng từ 0 lên hai tỷ.Java nhanh hơn C

Tôi thực sự mong đợi ngôn ngữ c sẽ nhanh hơn java. Tôi đã rất ngạc nhiên về kết quả:

thời gian cần thiết trong vài giây cho java: xấp xỉ. 1.8 giây

thời gian cần tính bằng giây cho c: xấp xỉ. 3.6 giây.

Tôi KHÔNG nghĩ rằng java là ngôn ngữ nhanh hơn chút nào, nhưng tôi KHÔNG hiểu tại sao vòng lặp nhanh gấp đôi c trong các chương trình đơn giản của tôi?

Tôi đã thực hiện một sai lầm quan trọng trong chương trình chưa? Hoặc là trình biên dịch của MinGW cấu hình kém hoặc một cái gì đó?

public class Jrand { 

public static void main (String[] args) { 

    long startTime = System.currentTimeMillis(); 
    int i; 
    for (i = 0; i < 2000000000; i++) { 
     // Do nothing! 
    } 
    long endTime = System.currentTimeMillis(); 
    float totalTime = (endTime - startTime); 

    System.out.println("time: " + totalTime/1000); 
} 

} 

THE C-CHƯƠNG TRÌNH

#include<stdio.h> 
#include<stdlib.h> 
#include <time.h> 
int main() { 

    clock_t startTime; 
    startTime = clock(); 

    int i; 
    for (i = 0; i <= 2000000000; i++) { 
     // Do nothing 
    } 
    clock_t endTime; 
    endTime = clock(); 

    float totalTime = endTime - startTime; 
    printf("%f", totalTime/1000); 

    return 0; 
} 
+3

Các vòng lặp có lẽ bị bỏ qua trong Java. Hãy thử làm điều gì đó có ý nghĩa trong vòng lặp, như cập nhật tổng và in nó sau vòng lặp. Xem thêm [chủ đề này] (http://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java) –

+4

Trình tối ưu hóa. Như Sanjay nói. – Devolus

+11

Bạn đã bật tối ưu hóa cho bản dựng C chưa?Tôi đoán bạn có lẽ đã không vì nếu không, mã C của bạn nên được trả lại 0 giây. – Mysticial

Trả lời

21

Tạo lại phiên bản C của bạn với bất kỳ mức tối ưu hóa nào khác ngoài -O0 (ví dụ: -O2) và bạn sẽ thấy nó chạy trong 0 giây. Vì vậy, phiên bản Java mất 1,6 giây để không phải làm gì, và phiên bản C mất 0,0 giây (thực sự, khoảng 0,00005 giây) để không phải làm gì cả.

+7

Có thể trên hệ thống của anh ấy. Ngày * lần đầu tiên chạy * của máy tính xách tay cũ của tôi (Core 2 Duo) phiên bản Java mất 0,059 giây ... Nó chỉ là thời gian khởi động của JVM, có lẽ là đĩa IO. Chỉ trong trường hợp có bất kỳ bashers Java nào ở đây. –

+0

cảm ơn! Tôi đã sử dụng -O2 và thêm một calc đơn giản. bên trong vòng lặp. ngôn ngữ c: 0,0000 ... giây. Java: 6,7 giây. Có thể sau này cũng được tối ưu hóa? –

+0

@owlstead: 0.059 giây phí khởi động là rất nhiều lý do để bash Java vẫn còn. Nó dài hơn frametime cho framerates điển hình/refresh-rate. –

10

Java là tích cực hơn ở loại bỏ mã mà không làm gì cả. Nó ít có khả năng giả định các nhà phát triển biết những gì họ đang làm. Bạn không định thời gian vòng lặp nhưng phải mất bao lâu để phát hiện và loại bỏ vòng lặp java.

Tóm lại, Java thường nhanh hơn khi không làm gì hữu ích.

Ngoài ra, bạn có thể thấy rằng nếu bạn tối ưu hóa mã C và xóa thông tin gỡ lỗi, nó sẽ thực hiện tương tự, rất có thể ngắn hơn.

+6

Bất kỳ trình biên dịch C nào chắc chắn sẽ không tạo ra mã nào cho vòng lặp vô dụng trừ khi bạn cố tình biên dịch với tối ưu hóa bị vô hiệu hóa, đó là một công cụ để đơn bước qua chương trình và có thể hiểu được dòng chảy của máy trừu tượng . –

1

Nếu bạn muốn điểm chuẩn này, thay vì không làm gì cả, hãy thử một cái gì đó hữu ích như tính toán một cái gì đó trên mỗi lần lặp. Ví dụ: đếm các vòng trong một số biến khác và đảm bảo bạn sử dụng nó ở cuối (bằng cách in nó cho ví dụ), để nó không được tối ưu hóa.

Kiểm tra đơn giản thay thế có thể truy cập một mảng tuyến tính (chỉ đọc), sao chép các phần tử từ mảng này sang mảng khác (đọc + ghi) hoặc thực hiện một số thao tác trên dữ liệu. Một số trường hợp này có thể thú vị khi chúng mở một số tối ưu hóa trình biên dịch rất đơn giản mà bạn có thể thấy trong kết quả nhị phân/bytecode, chẳng hạn như vòng lặp, phân bổ đăng ký và thậm chí có thể phức tạp hơn như vector hóa hoặc chuyển động mã. Java trên khác có thể sử dụng một số thủ thuật nastier như jitting (tự động biên dịch lại một cách nhanh chóng)

Phạm vi của trình biên dịch tối ưu hóa là rất lớn, bạn vừa gặp phải cơ bản nhất một - loại bỏ mã vô dụng :)