std::sort 並不總是調用std::swap
在某些情況下,std::sort 可能不會呼叫自訂交換為給定資料類型定義的函數。這種行為已在 GCC 的 stdlibc 實作中觀察到,並且在處理小範圍元素時尤其明顯。
為了提高效能效率,GCC 的 std::sort 實作對低於特定大小的範圍採用插入排序。這是因為對於小型資料集,插入排序比快速排序或內插排序更快。但是,插入排序不使用定義的交換函數。相反,它會直接移動整個元素範圍以實現更快的效能。
下面的程式碼片段說明了此行為:
<code class="cpp">#include <algorithm> #include <iostream> #include <vector> namespace my_space { struct A { double a; double* b; bool operator<(const A& rhs) const { return this->a < rhs.a; } }; void swap(A& lhs, A& rhs) { std::cerr << "My swap.\n"; std::swap(lhs.a, rhs.a); std::swap(lhs.b, rhs.b); } } int main() { const int n = 20; std::vector<my_space::A> vec(n); for (int i = 0; i < n; ++i) { vec[i].a = -i; } for (int i = 0; i < n; ++i) { std::cerr << vec[i].a << " "; } std::cerr << "\n"; std::sort(vec.begin(), vec.end()); for (int i = 0; i < n; ++i) { std::cerr << vec[i].a << " "; } std::cerr << "\n"; }</code>
當 n 設定為 20 時,呼叫自訂交換函數,並且陣列已正確排序。但是,如果 n 減少到 4,則不會呼叫自訂交換函數,但陣列仍然正確排序。
在處理複製成本高昂的物件時,此行為可能會出現問題。為了緩解此問題,請考慮使用始終呼叫提供的交換函數的 std::sort 實作。此外,您可能需要向 GCC 開發人員報告此行為以進行進一步優化。
以上是為什麼'std::sort”並不總是為小範圍呼叫'std::swap”?的詳細內容。更多資訊請關注PHP中文網其他相關文章!