Hướng dẫn how slow is c++ compared to c? - c ++ chậm như thế nào so với c?

Hướng dẫn how slow is c++ compared to c? - c ++ chậm như thế nào so với c?

Peter Xie

Ngày 13 tháng 7 năm 2020

4 phút đọc

Chậm hơn 45.000 lần!

Ảnh của Ben White trên unplash

Để so sánh hiệu suất tính toán giữa các ngôn ngữ Python và C, hãy để Lôi thực hiện một vòng cho tổng trong một giây. Bản thân mã là khá nhiều tự giải thích.

Python

Tôi sẽ bắt đầu bằng cách không đồng ý với một phần của câu trả lời được chấp nhận (và được trả lời tốt) cho câu hỏi này bằng cách nêu:

Thực tế có rất nhiều lý do tại sao mã JENT sẽ chạy chậm hơn một chương trình C ++ được tối ưu hóa đúng cách (hoặc ngôn ngữ khác không có thời gian chạy) bao gồm: including:

  • Tính toán các chu kỳ dành cho mã jit trong thời gian chạy theo định nghĩa không có sẵn để sử dụng trong thực thi chương trình.

  • Bất kỳ đường dẫn nóng nào trong jitter sẽ cạnh tranh với mã của bạn để hướng dẫn và bộ đệm dữ liệu trong CPU. Chúng tôi biết rằng bộ đệm thống trị khi nói đến hiệu suất và ngôn ngữ bản địa như C ++ không có loại tranh chấp này, theo thiết kế.

  • Ngân sách thời gian tối ưu hóa thời gian chạy nhất thiết phải bị hạn chế hơn nhiều so với số lượng tối ưu hóa thời gian biên dịch (như một nhà bình luận khác đã chỉ ra)

Điểm mấu chốt: Cuối cùng, bạn gần như chắc chắn sẽ có thể tạo ra một triển khai nhanh hơn trong C ++ so với C#..

Bây giờ, như đã nói, bao nhiêu thực sự không thể định lượng nhanh hơn bao nhiêu, vì có quá nhiều biến số: nhiệm vụ, miền vấn đề, phần cứng, chất lượng triển khai và nhiều yếu tố khác. Bạn sẽ có các bài kiểm tra trên kịch bản của mình để xác định sự khác biệt về hiệu suất, và sau đó quyết định xem nó có xứng đáng với nỗ lực và độ phức tạp bổ sung hay không.

Đây là một chủ đề rất dài và phức tạp, nhưng tôi cảm thấy đáng được đề cập vì tính đầy đủ của trình tối ưu hóa thời gian chạy của C#là tuyệt vời và có thể thực hiện một số tối ưu hóa động nhất định trong thời gian chạy đơn giản là không có sẵn cho C ++ với thời gian biên dịch của nó (thời gian biên dịch của nó ( Tĩnh) Trình tối ưu hóa. Ngay cả với điều này, lợi thế vẫn thường là sâu sắc trong tòa án của ứng dụng bản địa, nhưng trình tối ưu hóa động là lý do cho vòng loại "gần như chắc chắn" được đưa ra ở trên.almost certainly" qualifier given above.

-

Về mặt hiệu suất tương đối, tôi cũng bị xáo trộn bởi các số liệu và các cuộc thảo luận mà tôi đã thấy trong một số câu trả lời khác, vì vậy tôi nghĩ rằng tôi đã hòa nhập và đồng thời, cung cấp một số hỗ trợ cho các tuyên bố tôi đã đưa ra ở trên.

Một phần rất lớn của vấn đề với các điểm chuẩn đó là bạn không thể viết mã C ++ như thể bạn đang viết C# và hy vọng sẽ nhận được kết quả đại diện (ví dụ: thực hiện hàng ngàn phân bổ bộ nhớ trong C ++ sẽ cung cấp cho bạn những con số khủng khiếp.)

Thay vào đó, tôi đã viết mã C ++ thành ngữ hơn một chút và so sánh với mã C# @Wiory được cung cấp. Hai thay đổi chính tôi đã thực hiện đối với mã C ++ là:

  1. Vector đã qua sử dụng :: Dự trữ ()

  2. Làm phẳng mảng 2D thành 1D để đạt được bộ nhớ cache tốt hơn (khối liền kề)

C# (.NET 4.6.1)

private static void TestArray()
{
    const int rows = 5000;
    const int columns = 9000;
    DateTime t1 = System.DateTime.Now;
    double[][] arr = new double[rows][];
    for (int i = 0; i < rows; i++)
        arr[i] = new double[columns];
    DateTime t2 = System.DateTime.Now;

    Console.WriteLine(t2 - t1);

    t1 = System.DateTime.Now;
    for (int i = 0; i < rows; i++)
        for (int j = 0; j < columns; j++)
            arr[i][j] = i;
    t2 = System.DateTime.Now;

    Console.WriteLine(t2 - t1);
}

Thời gian chạy (Phát hành): init: 124ms, Fill: 165ms

C ++ 14 (Clang v3.8/C2)

#include 
#include 

auto TestSuite::ColMajorArray()
{
    constexpr size_t ROWS = 5000;
    constexpr size_t COLS = 9000;

    auto initStart = std::chrono::steady_clock::now();

    auto arr = std::vector();
    arr.reserve(ROWS * COLS);

    auto initFinish = std::chrono::steady_clock::now();
    auto initTime = std::chrono::duration_cast(initFinish - initStart);

    auto fillStart = std::chrono::steady_clock::now();

    for(auto i = 0, r = 0; r < ROWS; ++r)
    {
        for (auto c = 0; c < COLS; ++c)
        {
            arr[i++] = static_cast(r * c);
        }
    }

    auto fillFinish = std::chrono::steady_clock::now();
    auto fillTime = std::chrono::duration_cast(fillFinish - fillStart);

    return std::make_pair(initTime, fillTime);
}

Thời gian chạy (phát hành): init: 398

Tổng thời gian chạy: C#: 289ms, C ++ 152ms (nhanh hơn khoảng 90%)

Quan sát

  • Thay đổi triển khai C# thành cùng một triển khai mảng 1D mang lại init: 40ms, Fill: 171ms, Total: 211ms (C ++ vẫn nhanh hơn gần 40%).C++ was still almost 40% faster).

  • Việc thiết kế và viết mã "nhanh" trong C ++ khó hơn nhiều so với việc viết mã "thông thường" bằng ngôn ngữ.

  • Thật dễ dàng (có lẽ) dễ dàng để có được hiệu suất kém trong C ++; Chúng tôi đã thấy rằng với hiệu suất vectơ không được bảo vệ. Và có rất nhiều cạm bẫy như thế này.

  • Hiệu suất của C#là khá tuyệt vời khi bạn xem xét tất cả những gì đang diễn ra trong thời gian chạy. Và hiệu suất đó tương đối dễ dàng để truy cập.

  • Thêm dữ liệu giai thoại so sánh hiệu suất của C ++ và C#: https://benchmarksgame.alioth.debian.org/u64q/compare.php?lang=gpp&lang2=csharpcore

Điểm mấu chốt là C ++ cung cấp cho bạn nhiều quyền kiểm soát hiệu suất hơn. Bạn có muốn sử dụng một con trỏ? Một tài liệu tham khảo? Bộ nhớ xếp chồng? Đống? Đa hình động hoặc loại bỏ chi phí thời gian chạy của VTable với đa hình tĩnh (thông qua các mẫu/CRTP)? Trong C ++, bạn phải ... er, hãy tự mình thực hiện tất cả các lựa chọn này (và hơn thế nữa), lý tưởng nhất là giải pháp của bạn giải quyết tốt nhất vấn đề bạn đang giải quyết.

Hãy tự hỏi mình nếu bạn thực sự muốn hoặc cần sự kiểm soát đó, bởi vì ngay cả đối với ví dụ tầm thường ở trên, bạn có thể thấy rằng mặc dù có một sự cải thiện đáng kể về hiệu suất, nhưng nó đòi hỏi một khoản đầu tư sâu hơn để truy cập.

C hay C nhanh hơn?

Dựa trên hiệu suất dựa trên bản chất của ngôn ngữ C ++ là ngôn ngữ lập trình hướng đối tượng và nó hỗ trợ một số tính năng quan trọng như đa hình, loại dữ liệu trừu tượng, đóng gói, v.v. Vì nó hỗ trợ định hướng đối tượng, tốc độ nhanh hơn so với ngôn ngữ C.speed is faster compared to the C language.

C ++ đến C chậm hơn bao nhiêu?

Hyperfine cho tôi biết rằng chương trình C ++ dựa vào thư viện C ++ được tải động mất gần 1 ms thời gian so với chương trình C.almost 1 ms more time than the C program.

C nhanh hơn C VS C ++?

C nhanh hơn C ++ C ++ cho phép bạn viết các bản tóm tắt biên dịch xuống tương đương C. Điều này có nghĩa là với một số chăm sóc, một chương trình C ++ sẽ ít nhất là nhanh như một C.Lợi thế C ++ mang lại so với C là nó cho phép chúng ta cũng xây dựng các trừu tượng có thể tái sử dụng với các mẫu, OOP và thành phần chức năng. C++ allows you to write abstractions that compile-down to equivalent C. This means that with some care, a C++ program will be at least as fast as a C one. The advantage C++ gives over C is that it enables us to also build reusable abstractions with templates, OOP and functional composition.

Bao nhiêu chậm hơn C?

Trong các kết quả này thường đi một nửa tốc độ của C, nhưng nhanh hơn 50 lần so với Python.half the speed of C, but 50 times faster than python.