Công cụ phát triển: Trình biên dịch C/C++

tốt nhất?

Mặc dù xuất hiện nhiều ngôn ngữ lập trình và công nghệ mới, C++ vẫn là công cụ

chính của nhiều nhà phát triển, có thể vị trí của nó sẽ vẫn được duy trì nhiều năm

nữa. C++ nổi bật về sự linh động, tính khả chuyển, hiệu quả và tốc độ. Mặc dù

năng lực xử lý của máy tính đã có sự gia tăng đáng kể, hiệu suất phần mềm vẫn là

yếu tố quan trọng, C++ là ngôn ngữ sẽ cho hiệu suất vượt trội hầu như về mọi

phương diện nếu được sử dụng một cách đúng đắn.

Bài viết này so sánh 9 trình biên dịch C++ phổ biến, đánh giá về hiệu suất, tính

năng và công cụ. Các trình biên dịch (TBD) hoặc là chỉ hỗ trợ môi trường Win32,

hoặc là hỗ trợ các biến thể khác Win32. Việc kiểm tra đánh giá được thực hiện

trên 1 máy Windows XP Pro (1 BXL 2GHz, 512MB RAM) hoàn toàn không chạy

các tác vụ khác.

Thời gian biên dịch

Trong nhiều trường hợp, thời gian biên dịch không quan trọng. Tuy nhiên, nó là

yếu tố then chốt trong các hệ thống lớn hay trong môi trường phát triển thường

hay biên dịch ứng dụng (như trong mô hình phát triển eXtreme Programming).

Các yếu tố quan trọng trong quá trình biên dịch/liên kết mã nguồn bao gồm: số

lượng các thư viện, sử dụng các thành phần được biên dịch trước, độ phức tạp của

mã lệnh, yêu cầu về tối ưu (cho cả biên dịch và liên kết) và kích thước các mô đun

biên dịch. Các tình huống được xem xét:

1. C1. Một file C lớn (1000 hàm), duy nhất (không 'include'); chỉ biên dịch, không

tối ưu.

2. C2. Một file C với số lượng file include lớn (500); chỉ biên dịch, không tối ưu.

3. C3. Một file C với số lượng file include lồng nhau nhiều cấp (100), mỗi file

được include bởi file trước nó và file main. Thử nghiệm đánh giá ảnh hưởng của

việc include nhiều cấp; chỉ biên dịch không tối ưu.

4. pch. Một bộ file C++ (main.cpp, pch.cpp và 40 file lớp .h/.cpp) dùng chung

header, (biên dịch và liên kết; các header được biên dịch trước; không tối ưu).

5. whereis. Một file C++ duy nhất nhưng phức tạp với nhiều include thư viện hệ

điều hành và template (chỉ biên dịch; tối ưu về kích thước).

6. MMComBsc. Thư viện DLL lớn (44 file nguồn C và 37 file nguồn C++, 111

file header, kích thước biên dịch 80KB) bao gồm các hàm COM và các lớp (biên

dịch và liên kết; các header được biên dịch trước; tối ưu về kích thước).

7. zlib. Thư viện nén dữ liệu tổng quát và miễn phí, có thể chạy trên nhiều nền

tảng hệ thống.

Dùng các script Python (http://www.ddj.com/ftp/2003/200310/cppcomp.zip) để

tạo các file nguồn cho các tình huống 1- 4. Mã nguồn whereis có ở

http://stlsoft.org/ (file nhị phân cập nhật có ở

http://synesis.com.au/r_systools.html). Các file nguồn cho MMComBs.dll có

nhiều thứ liên quan đến vấn đề bản quyền vì vậy bạn tạm chấp nhận thông tin cung

cấp ở đây!

Kết quả kiểm tra các tình huống 1- 3 và 5 được lấy với ptime

(http://synesis.com.au/r_systools.html) bằng cách thực hiện nhiều lần (15 lần), bỏ

qua 2 kết quả cao nhất và 1 kết quả thấp nhất, còn lại lấy trung bình nhằm giảm sai

lệch do bước đệm hoặc khởi động. Kiểm tra các tình huống 4, 6 và 7 dùng các

makefile, đo thời gian bằng ptime. Các kết quả kiểm tra được thể hiện trong Bảng

1.

Khái niệm 'Did Not Compile' (DNC, không biên dịch) của CodeWarrior trong các

kết quả ở tình huống C3 là do TBD từ chối xử lý include lồng nhau lên tới 100

cấp; các thử nghiệm cho thấy số cấp giới hạn là 30. Thông tin trợ giúp của

CodeWarrior: 'Để khắc phục vấn đề này, hãy nghiên cứu trình tự lô gic ẩn đằng

sau các #include lồng nhau. Có thể có cách tách các #include lồng nhau nhiều cấp

thành một loạt #include lồng nhau ít cấp hơn' - điều này có thể đúng nhưng không

phải lúc nào cũng có thể thực hiện được. Watcom có thể không biên dịch các tình

huống whereis và MMComBsc vì nó không hỗ trợ template hiệu quả.

Có một số khác biệt đáng kể về hiệu suất. Borland tỏ ra tốt nhất, theo sát là VC++

6, Digital Mars và VC++ 7 đồng hạng 3. CodeWarrior, GCC và Intel là các TBD

chậm chạp nhất trong nhóm. VC++ 7 biên dịch pch nhanh hơn 43 lần so với

CodeWarrior! VC++ 7.1 chậm hơn VC++ 7.0 trong mọi thử nghiệm.

Tốc độ sinh mã

Kế tiếp chúng ta xem xét tốc độ sinh mã, giới hạn ở 5 tình huống sau:

1. Dhrystone (http://www.webopedia .com/TERM/D/Dhrystone.html). Phép đo

này kiểm tra tốc độ tính toán số nguyên. Vì nó sử dụng toàn bộ CPU (không có bất

kỳ tác vụ truy cập tài nguyên hay I/O nào trong quá trình kiểm tra), đây là phép đo

tốt về tốc độ mã lệnh đã được biên dịch. Tốc độ được đo với số Dhrystone trong 1

giây (số càng lớn càng tốt).