2012-12-17 12 views
5

Viết chương trình thể hiện thuật toán sắp xếp khác nhau trong C++ trên Mac. Tôi tìm thấy hai triển khai quicksort, qsort và qsort_b.qsort_b và qsort

Điều đầu tiên tất nhiên là qsort cũ, được xem ở mọi nơi. Nhưng có qsort_b, một khối thay vì một hàm. Đây là mã của tôi:

#include <cstdlib> 
#include <cstdio> 
#include <iostream> 
#include <cstdio> 
#include <ctime> 

#define DATA 1000000 

using namespace std; 

int compare(const void* a, const void* b) 
{ 
    return *(int*)a - *(int*)b; 
} 

int main(int argc, char *argv[]) 
{ 
    int* array = new int[DATA]; 

    srand(time(0)); 

    for (int i = 0 ; i < DATA ; ++ i) 
    { 
     array[i] = rand() % 2147483647; 
    } 

    clock_t begin = clock(); 

    qsort(array, DATA, sizeof(array[0]), compare); 
    //qsort_b(array, DATA, sizeof(array[0]), ^(const void* a, const void* b) { return *(int*)a - *(int*)b; }); 

    clock_t end = clock(); 

    cout << "Time it takes to sort " << DATA << " integers with quicksort: " << end - begin; 
} 

Ở đây tôi thấy sự khác biệt về tốc độ lớn, điều gì gây ra sự khác biệt đó. Theo hiểu biết của tôi, các khối là để xử lý song song, trong trường hợp này sẽ không nhanh hơn các hàm. Không có gì để xử lý song song, phải không? EDIT: Các thói quen heapsort_b(), mergesort_b(), và qsort_b() giống như các thói quen tương ứng không có hậu tố _b, hy vọng rằng hàm gọi lại so sánh là một con trỏ khối thay vì một con trỏ hàm. (FROM BSD MAN PAGE)

EDIT: Chênh lệch tốc độ. Với DATA là 1000000, qsort đã hoàn thành nó trong 146832 ns, với qsort_b, trong 127391 ns. Đó là một sự khác biệt khá lớn so với việc nó nhanh hơn khoảng 10%.

EDIT: Tôi đã chỉnh sửa mã để làm cho nó có thể có mảng lớn hơn các số nguyên. Kết quả thử nghiệm lớn nhất cá nhân của tôi là 100000000 số nguyên, 28136278 (28) so với 23870078 (24 giây). Đó là một sự khác biệt lớn đáng kể đối với tôi.

+0

bạn có thể giải thích thêm về "chênh lệch tốc độ lớn" –

+0

@KarthikT Tôi không chắc chắn với đơn vị đo lường, nhưng tôi nghĩ rằng đó là nano giây. Với qsort, nó là 146832, với qsort_b, nó là 127391. Với DATA là 1000000. –

+0

Tôi đã thử nghiệm nó với dữ liệu lớn hơn bao giờ hết, 100000000 số nguyên. Đó là 28136278 (28) so với 23870078 (24 giây). Đó là một sự khác biệt lớn đáng kể đối với tôi. –

Trả lời

3

Mục tiêu-C Block là một loại động vật khác. Nó có thể giống như MACRO (thay thế trước khi biên soạn) và inline functions (nói với trình biên dịch "Làm tốt nhất của bạn để loại bỏ phí gọi hàm"), nhưng cấu trúc tổng thể khác nhiều hơn các cấu trúc đó.

Block là một đối tượng, hơn nữa, một chồng đối tượng. Đối tượng duy nhất được phép tạo trong ngăn xếp (ít nhất là không có một số thủ thuật).

Khi đối tượng Block được tạo trong ngăn xếp, trình biên dịch thêm tất cả biến cục bộ, biến khối, địa chỉ của biến đọc/ghi mà tham chiếu và con trỏ vào mã thực thi của khối. Vì vậy, ngay cả trước khi bắt đầu thực hiện, mọi thứ đã sẵn sàng để tính toán mà không cần bất kỳ hoạt động ngăn xếp nào.

Vì vậy, đó không phải là vấn đề tối ưu hóa, thay vì thuộc tính của Block. Nó không có bất kỳ chi phí gọi hàm nào của PUSHPOP s của các biến ngăn xếp.

Là một câu trả lời cho câu hỏi của bạn, qsort()qsort_b() không có bất kỳ sự khác biệt thuật toán, nhưng cấu trúc xây dựng, khối vs chức năng.

2

Dường như sự khác biệt tối ưu hóa đối với tôi. Với qsort_b, trình biên dịch có thể inlines so sánh, trong khi với qsort thì không. Sự khác biệt là chi phí của cuộc gọi hàm trên mỗi so sánh.

+0

Bạn phải chính xác. Đúng nếu tôi sai, các khối giống như chức năng nội tuyến trong tình huống cụ thể này. Và các hàm nội tuyến được coi là nhanh hơn hàm. (http://stackoverflow.com/questions/4016061/why-is-inlining-considered-faster-than-a-function-call) –

+0

@ShaneHsu Tôi không biết gì về những "khối" khác với những gì tôi đọc chỉ bây giờ từ http://en.wikipedia.org/wiki/Blocks_(C_language_extension) vì vậy không thể bình luận về loại mã trình biên dịch tạo ra cho chúng. Nếu bạn muốn thực sự hiểu những gì đang diễn ra, hãy thêm trình chuyển đổi dòng lệnh trình biên dịch để tạo các tệp nguồn asm (thay vì tệp đối tượng) cho cả hai trường hợp và so sánh chúng. Một thử nghiệm khác có thể là thử cả hai phiên bản có tối ưu hóa bị tắt và sau đó quay lên tối đa và xem nó ảnh hưởng như thế nào đến hiệu suất tương đối. – hyde

+0

Sẽ thực hiện thí nghiệm sau đó. Cảm ơn! –