我有一個看起來像Boost.Array的簡單類。有兩個模板參數T和N.Boost.Array的一個缺點是每個使用這種數組的方法都必須是一個帶參數N(T是OK)的模板。其結果是整個程序往往是一個模板。一個想法是創建一個僅依賴於T的接口(僅具有純虛函數的抽象類)(類似於ArrayInterface)。現在每個其他類只訪問該接口,因此只需要模板參數T(與N相反,或多或少總是已知)。這裏的缺點是虛擬呼叫的開銷(更多錯過內聯呼叫的機會),如果使用接口的話。直到這裏只有事實。接口開銷
template<typename T>
class ArrayInterface {
public:
virtual ~ArrayInterface() {};
virtual T Get(int i) = 0;
};
template<typename T, int N>
class Array : ArrayInterface<T> {
public:
T Get(int i) { ... }
};
template<typename T, int N>
class ArrayWithoutInterface {
public:
T Get() { ... }
};
但我真正的問題在於別的地方。當我使用接口來擴展Boost.Array時,Boost.Array的直接實例化變得緩慢(在一種情況下,因素4是重要的)。如果我刪除接口,Boost.Array和以前一樣快。我明白,如果一個方法通過ArrayInterface被調用,那麼會有開銷,這是可以的。但是我不明白爲什麼對一個方法的調用會變慢,如果只有一個只有純虛擬方法的接口,並且這個類是直接調用的。
Array<int, 1000> a;
a.Get(0); // Slow
ArrayWithoutInterface<int, 1000> awi;
awi.Get(0); // Fast
GCC 4.4.3和Clang 1.1顯示相同的行爲。
我很清楚,在正常情況下,後期綁定有一個缺點,如上面所寫。但我不明白爲什麼這一點很重要,因爲編譯器可以消除IMO的開銷。 – azraiyl 2010-11-05 13:35:06
@azraiyl如果你正在談論虛擬化,那麼這是一個非常非常先進的優化。編譯器很聰明,但不是那麼聰明。 – 2010-11-05 13:37:09
是的,虛擬化(好詞)是我認爲應該可以在這裏。 – azraiyl 2010-11-05 13:46:58