Home Item 9 - constexpr (中文)
Post
Cancel

Item 9 - constexpr (中文)

constexpr 關鍵字

C++11 引入了 constexpr 關鍵字,用於宣告可以在編譯時求值的函數或變數。 這樣的函數或變數可以在編譯時被求值,而不是在運行時,從而提高了程式的性能和效率。 constexpr 的使用時機通常是在需要在編譯時計算值的情況下,例如在模板元編程中、在宣告常數表達式時等。

簡單的來說,就是把執行時計算的時間移到 complie 時。

這麼好要不要全部 function 都改成 constexpr ? No !

不適合使用 constexpr 的一些例子

  1. 需要在運行時決定的情況: 如果變數的值需要在程式運行時才能確定,而不是在編譯時就能決定,那麼就不適合使用 constexpr。比如從使用者輸入獲取的數值,或者需要從外部文件讀取的數值。

  2. 依賴外部狀態的情況: 如果函數或變數的計算依賴於外部狀態的變化,而該外部狀態無法在編譯時獲取,那麼也不適合使用 constexpr。例如需要訪問系統時間或文件系統狀態的情況。

  3. 過於複雜的運算邏輯: 如果函數或變數的計算邏輯過於複雜,無法在編譯時完全展開和求值,那麼也不適合使用 constexprconstexpr 函數的計算在編譯時進行,如果計算邏輯過於複雜會增加編譯時間和編譯器的負擔。

驗證

以下我們特別來驗證 constexpr 增加編譯時間的部分。

計算的絕對時間不是重點,因為硬體等其他因素會造成每個電腦上編譯時間都不同, 但相對時間的差異,確實可以看出效果。

1
constexpr int result = fibonacci_constexpr(27);

Desktop View

其他三次分別為: 3.9, 3.8, 3.4 秒

1
int result = fibonacci_constexpr(27);

Desktop View

其他三次分別為: 1.8, 1.9, 1.8 秒

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
#include <chrono>

 constexpr int fibonacci_constexpr(int n) {
     return (n <= 1) ? n : fibonacci_constexpr(n - 1) + fibonacci_constexpr(n - 2);
 }

 int fibonacci(int n) {
     return (n <= 1) ? n : fibonacci(n - 1) + fibonacci(n - 2);
 }

 int main() {


     auto start = std::chrono::high_resolution_clock::now();

     // 在編譯時求值
     constexpr int result = fibonacci_constexpr(27);

     auto end = std::chrono::high_resolution_clock::now();

     std::chrono::duration<double> duration = end - start;

     std::cout << "Calculate at compile time: " << std::endl;
     std::cout << "time: " << duration.count() << " (s)" << std::endl;

     std::cout << "-----------------" << std::endl;

     start = std::chrono::high_resolution_clock::now();
     // 在 runtime 時求值
     int result2 = fibonacci(27);

     end = std::chrono::high_resolution_clock::now();

     duration = end - start;
     std::cout << "Calculate at run time: " << std::endl;
     std::cout << "time: " << duration.count() << " (s)" << std::endl;


     return 0;
 }


結果

Desktop View

執行時計算時間,而 fibonacci_constexpr(27) 在 compile 時已經計算完畢,在執行時只是一個常數被帶入。 因此執行速度很快。 反之,fibonacci 在 runtime 時才去計算,可以從計算時間看出巨大的差異。

應該很清楚了吧,哈 !

☝ツ☝

This post is licensed under CC BY 4.0 by the author.

👈 ツ 👍

C++ 引用防護(中文)

Item 9 - constexpr (English)