[英]How can an addition operator for a C++ class container be optimized?
考慮
class abc
{
public:
map<int,double> data;
abc(map<int,double> && in):data(std::move(in)){}
abc operator + (const abc & in)
{
auto tmp = data;
for( auto & itr : in.data)
tmp[itr.first] += itr.second;
return abc(std::move(tmp));
}
};
我想更好的實現可能是
abc operator + (const abc & in)
{
auto &tmp1 = (data.size() > in.data.size() ? data : in.data);
auto &tmp2 = (data.size() > in.data.size() ? in.data : data);
auto tmp = tmp1;
for( auto & itr : tmp2)
tmp[itr.first] += itr.second;
return abc(std::move(tmp));
}
我想要實現的是,例如,如果我有一個發言,
S = A+B+C+D+E
並假設B
, C
和D
為空,則成本應與
S = A+E
從本質上講,如果abc
類型為零,我不想花費成本。 有辦法實現嗎?
我認為您會在以下方面做得更好:
abc operator + (abc lhs, const abc& rhs) // Note 'lhs' by value.
{
for(const auto & val : rhs.data)
lhs.data[val.first] += val.second;
return lhs; // Rely on NRVO
}
選擇按值取參數的原因是,如果它是臨時的(例如A + B
的結果),則不需要復制。 編譯器可以直接傳遞臨時變量。
編輯 WhiZTiM建議的代理將更加高效,因為它將所有內容推遲到了最后。 它依賴於這樣的事實,即直到完整表達式的結尾才臨時銷毀臨時文件。
struct Proxy
{
std::vector<const abc*> values;
operator abc() {
assert(values.size() > 2);
abc result = *(values.back()); // Can't avoid one copy.
values.pop_back();
for (const auto& v : values)
for (const auto& key_value : v->data)
result.data[key_value.first] += key_value.second;
return result;
}
};
Proxy operator +(const abc &lhs, const abc& rhs) {
Proxy result;
result.values.push_back(&lhs);
result.values.push_back(&rhs);
return result;
}
Proxy operator +(Proxy lhs, const abc& rhs) {
lhs.values.push_back(&rhs);
}
Proxy operator +(const abc& lhs, Proxy rhs) {
rhs.values.push_back(&lhs);
}
Proxy operator +(Proxy lhs, const Proxy& rhs) {
// implementation left as an exercise for the reader.
}
注意:以上未公開給編譯器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.