Tôi là một nhà phát triển C ++ và C #. Tôi đã phát triển các ứng dụng C # kể từ bản beta đầu tiên của .NET framework và tôi đã có hơn 20 năm kinh nghiệm trong việc phát triển các ứng dụng C ++. Thứ nhất, mã C # sẽ KHÔNG BAO GIỜ nhanh hơn ứng dụng C ++, nhưng tôi sẽ không thảo luận dài dòng về mã được quản lý, cách nó hoạt động, lớp inter-op, nội bộ quản lý bộ nhớ, hệ thống kiểu động và bộ thu gom rác. Tuy nhiên, hãy để tôi tiếp tục bằng cách nói rằng các điểm chuẩn được liệt kê ở đây đều cho kết quả KHÔNG ĐÚNG.
Để tôi giải thích: Điều đầu tiên chúng ta cần xem xét là trình biên dịch JIT cho C # (.NET Framework 4). Bây giờ JIT tạo mã gốc cho CPU bằng cách sử dụng các thuật toán tối ưu hóa khác nhau (có xu hướng tích cực hơn trình tối ưu hóa C ++ mặc định đi kèm với Visual Studio) và tập lệnh được sử dụng bởi trình biên dịch .NET JIT là sự phản ánh gần gũi hơn với CPU thực tế trên máy để có thể thực hiện một số thay thế nhất định trong mã máy để giảm chu kỳ xung nhịp và cải thiện tốc độ truy cập trong bộ đệm đường ống CPU và tạo ra các tối ưu hóa siêu phân luồng hơn nữa, chẳng hạn như chúng tôi sắp xếp lại lệnh và cải tiến liên quan đến dự đoán nhánh.
Điều này có nghĩa là trừ khi bạn biên dịch ứng dụng C ++ của mình bằng cách sử dụng các tham số chính xác cho bản dựng RELEASE (không phải bản dựng GỬI) thì ứng dụng C ++ của bạn có thể hoạt động chậm hơn ứng dụng dựa trên C # hoặc .NET tương ứng. Khi chỉ định các thuộc tính dự án trên ứng dụng C ++ của bạn, hãy đảm bảo bạn bật "tối ưu hóa hoàn toàn" và "ưu tiên mã nhanh". Nếu bạn có máy 64 bit, bạn PHẢI chỉ định tạo x64 làm nền tảng đích, nếu không mã của bạn sẽ được thực thi thông qua lớp con chuyển đổi (WOW64) sẽ làm giảm đáng kể hiệu suất.
Khi bạn thực hiện tối ưu hóa chính xác trong trình biên dịch, tôi nhận được .72 giây cho ứng dụng C ++ và 1,16 giây cho ứng dụng C # (cả hai đều trong bản dựng phát hành). Vì ứng dụng C # rất cơ bản và phân bổ bộ nhớ được sử dụng trong vòng lặp trên ngăn xếp chứ không phải trên đống, nên nó thực sự hoạt động tốt hơn rất nhiều so với một ứng dụng thực liên quan đến các đối tượng, tính toán nặng và với các tập dữ liệu lớn hơn. Vì vậy, những con số được cung cấp là những con số lạc quan, thiên về C # và .NET framework. Ngay cả với sự thiên vị này, ứng dụng C ++ hoàn thành chỉ trong hơn một nửa thời gian so với ứng dụng C # tương đương. Hãy nhớ rằng trình biên dịch C ++ của Microsoft mà tôi đã sử dụng không có đúng đường dẫn và tối ưu hóa siêu phân luồng (sử dụng WinDBG để xem hướng dẫn lắp ráp).
Bây giờ nếu chúng ta sử dụng trình biên dịch Intel (nhân tiện là bí mật ngành để tạo các ứng dụng hiệu suất cao trên bộ xử lý AMD / Intel), thì cùng một mã thực thi trong .54 giây đối với tệp thực thi C ++ so với .72 giây khi sử dụng Microsoft Visual Studio 2010 Vì vậy, cuối cùng, kết quả cuối cùng là .54 giây cho C ++ và 1.16 giây cho C #. Vì vậy, mã do trình biên dịch .NET JIT tạo ra mất thời gian dài hơn 214% so với mã thực thi C ++. Phần lớn thời gian trong .54 giây là để lấy thời gian từ hệ thống chứ không phải trong chính vòng lặp!
Điều còn thiếu trong số liệu thống kê là thời gian khởi động và dọn dẹp không được bao gồm trong thời gian. Các ứng dụng C # có xu hướng dành nhiều thời gian cho việc khởi động và kết thúc hơn các ứng dụng C ++. Lý do đằng sau điều này là phức tạp và liên quan đến các quy trình xác thực mã thời gian chạy .NET và hệ thống con quản lý bộ nhớ thực hiện rất nhiều công việc ở phần đầu (và do đó là phần cuối) của chương trình để tối ưu hóa việc cấp phát bộ nhớ và rác. người thu tiền.
Khi đo hiệu suất của C ++ và .NET IL, điều quan trọng là phải xem mã lắp ráp để đảm bảo rằng TẤT CẢ các phép tính đều ở đó. Những gì tôi nhận thấy là nếu không đặt một số mã bổ sung vào C #, hầu hết mã trong các ví dụ trên đã thực sự bị xóa khỏi hệ nhị phân. Đây cũng là trường hợp của C ++ khi bạn sử dụng trình tối ưu hóa tích cực hơn, chẳng hạn như trình tối ưu hóa đi kèm với trình biên dịch Intel C ++. Kết quả tôi cung cấp ở trên là đúng 100% và được xác nhận ở cấp độ lắp ráp.
Vấn đề chính của rất nhiều diễn đàn trên internet mà rất nhiều người mới nghe Microsoft tuyên truyền về marketing mà không hiểu công nghệ và tuyên bố sai rằng C # nhanh hơn C ++. Tuyên bố là về lý thuyết, C # nhanh hơn C ++ vì trình biên dịch JIT có thể tối ưu hóa mã cho CPU. Vấn đề với lý thuyết này là có rất nhiều hệ thống ống nước tồn tại trong .NET framework làm chậm hiệu suất; hệ thống ống nước không tồn tại trong ứng dụng C ++. Hơn nữa, một nhà phát triển có kinh nghiệm sẽ biết trình biên dịch phù hợp để sử dụng cho nền tảng nhất định và sử dụng các cờ thích hợp khi biên dịch ứng dụng. Trên nền tảng Linux hoặc mã nguồn mở, đây không phải là vấn đề vì bạn có thể phân phối mã nguồn của mình và tạo tập lệnh cài đặt biên dịch mã bằng cách sử dụng tối ưu hóa thích hợp. Trên cửa sổ hoặc nền tảng mã nguồn đóng, bạn sẽ phải phân phối nhiều tệp thực thi, mỗi tệp có các tối ưu hóa cụ thể. Các tệp nhị phân cửa sổ sẽ được triển khai dựa trên CPU được phát hiện bởi trình cài đặt msi (sử dụng các hành động tùy chỉnh).