C# Tại sao phép chia chậm hơn phép nhân?

Trong các ngôn ngữ lập trình và cụ thể là C# có 4 phép tính số học có thể được thực hiện: cộng, trừ, nhân và chia.

Và nhìn từ góc độ bên ngoài, có vẻ như tất cả chúng đều giống nhau về hiệu suất, nhưng hóa ra một trong số chúng chậm hơn nhiều so với 3 cái còn lại.

Bạn có thể hỏi cái nào chậm hơn? Phân chia.

Theo bài báo HP này:

Phép chia dấu phẩy động và căn bậc hai mất nhiều thời gian tính toán hơn so với phép cộng và phép nhân. Hai cái sau được tính trực tiếp trong khi cái trước thường được tính bằng thuật toán lặp. Cách tiếp cận phổ biến nhất là sử dụng phép lặp Newton-Raphson không chia để lấy xấp xỉ nghịch đảo của mẫu số (phép chia) hoặc căn bậc hai nghịch đảo, sau đó nhân với tử số (phép chia) hoặc đối số đầu vào (căn bậc hai).

Để xác minh tuyên bố trên, tôi quyết định chạy thử nghiệm đơn giản bằng mã bên dưới:

        //Generate two random numbers
        var rand = new System.Random();
        float a = rand.Next();
        float b = rand.Next();

        Debug.Log("Number a: " + a + " Number b: " + b);

        System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();

        watch.Start();
        //Addition
        for (int i = 1; i < 1000000; i++)
        {
            float tmp = a + b;
        }
        watch.Stop();
        //Output
        Debug.Log("Addition took: " + watch.Elapsed.TotalSeconds.ToString("0.0000") + " seconds");

        watch.Reset();
        watch.Start();
        //Subtraction
        for (int i = 1; i < 1000000; i++)
        {
            float tmp = a - b;
        }
        watch.Stop();
        //Output
        Debug.Log("Subtraction took: " + watch.Elapsed.TotalSeconds.ToString("0.0000") + " seconds");

        watch.Reset();
        watch.Start();
        //Multiplication
        for (int i = 1; i < 1000000; i++)
        {
            float tmp = a * b;
        }
        watch.Stop();
        //Output
        Debug.Log("Multiplication took: " + watch.Elapsed.TotalSeconds.ToString("0.0000") + " seconds");

        watch.Reset();
        watch.Start();
        //Division
        for (int i = 1; i < 1000000; i++)
        {
            float tmp = a / b;
        }
        watch.Stop();
        //Division
        Debug.Log("Division took: " + watch.Elapsed.TotalSeconds.ToString("0.0000") + " seconds");

Về cơ bản, tôi đã thực hiện một triệu phép cộng, trừ, nhân và chia cho hai số ngẫu nhiên và đo thời gian xử lý mỗi số đó, bài kiểm tra được lặp lại 5 lần và đây là kết quả:

  • Việc bổ sung trung bình mất 0,0004 giây
  • Phép trừ trung bình mất 0,0003 giây
  • Phép nhân trung bình mất 0,0003 giây
  • Phân chia trung bình mất 0,0044 giây

Kết quả cho thấy phép cộng, phép trừ và phép nhân có hiệu suất tương tự nhau nhưng phép chia có vẻ chậm hơn khoảng 1100%.

Một sự khác biệt không nhỏ, dẫn đến kết luận rằng sử dụng phép nhân thay vì phép chia luôn tốt hơn bất cứ khi nào có thể. Ví dụ: khi bạn cần chia số cho 2, tốt nhất nên nhân số đó với 0,5.