[英]evaluate expression at compile time
我知道這已經被問了很多,但僅限於 C/C++ 和 Java。 問題與使用常量表達式的性能優勢有關:
當我調用一個只有常量作為參數的靜態函數時,有沒有辦法告訴編譯器它應該在編譯時評估調用並用結果替換調用?
例子:
const double pi = Math.PI; //works as Math.PI is a constant
const double spi = Math.Sin(Math.PI); //compiler error, because expression must be constant
是否沒有指令(更好:屬性)明確地告訴編譯器像 Math.Sin() 這樣的靜態方法不會在內部修改或讀取任何數據,以便在技術上可以在編譯時評估調用?
哦,請不要回答像“just do const double spi = 0
”:),因為我的示例只是我遇到的問題的簡化版本:在保持最大性能的同時提高代碼可維護性。
感謝您的幫助 - 非常感謝!
對於數值常數,我看到兩個選項:
選項一:使用靜態只讀(啟動時計算一次):
class MyCalc
{
private static readonly double spi = Math.Sin(Math.PI);
private static readonly double pi = Math.PI;
public void Execute()
{
// .. whatever
}
}
選項二:使用您的袖珍計算器進行計算並對這些常量進行硬編碼:
class MyCalc
{
// Math.Sin(Math.Pi)
private const double spi = 0;
// Math.Pi
private const double pi = 3.141592653589793;
public void Execute()
{
// .. whatever
}
}
我不確定編譯器是否可以在計算中完全優化掉選項一,但它應該是最具可讀性和可維護性的方式。
如果您正在尋找盡可能多的在編譯時做的事情,事情會變得更難。 在 C++ 下,您有模板。 我發現它們寫起來很麻煩,但人們用它完成了驚人的事情。 使用 編譯時函數似乎更容易,但我還沒有嘗試過。 D 有CTFE這真的很強大。 但是 D 是一個利基,我會避免在其中編寫任何嚴肅的代碼。 我不知道其他語言有相當明確的預編譯評估,但我確定有一些。
如今,編譯器非常聰明。 編譯器可能會看到有機會在沒有提示的情況下優化函數調用。 在 DotNet 4.5 中,我們獲得了AggressiveInlining屬性,因此我們可以強制編譯器朝着正確的方向發展。 C/C++ 有類似的東西,並且出現了問題。 我這邊的一般建議是避免inline
直到您完全知道自己在做什么。
如果你真的不想從 C# 走這條路,我認為最好的選擇是使用提到的功能在 C++ 中編寫你的功能,編寫一個易於使用的 C 接口並通過PInvoke調用它。 但是,如果真的值得,請先幫自己一個忙並衡量一下。 永遠不要忘記優化的兩條規則:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.