Меня очень беспокоит производительность и читаемость кода, и я получаю большинство своих идей от Chandler Carruth от Google. Я бы хотел применить следующие правила для С++ для чистого кода, не теряя при этом производительности вообще.
- Передать все типы встроенных в качестве значений
- Передайте все объекты, которые вы не хотите мутировать с помощью ссылки const
- Передайте все объекты, которые ваша функция должна потреблять по значению
- Запретить все остальное. Когда в угловых случаях передайте указатель.
Таким образом, функции не имеют побочных эффектов. Это необходимо для чтения кода и делает С++ видом функционального. Теперь идет производительность. Что вы можете сделать, если хотите написать функцию, которая добавляет 1 к каждому элементу std::vector? Вот мое решение.
std::vector<int> add_one(std::vector<int> v) {
for (std::size_t k = 0; k < v.size(); ++k) {
v[k] += 1;
}
return v;
}
...
v = add_one(std::move(v));
...
Я нахожу это очень элегантным и делает всего 2 хода. Вот мои вопросы:
- Является ли это законным С++ 11?
- Как вы думаете, какой недостаток в этом дизайне?
- Не удалось ли компилятору автоматически преобразовать v = f (v) в это? Это своего рода копия.
PS: Люди спрашивают меня, почему я не люблю проходить по ссылке. У меня есть 2 аргумента:
1 - Он не делает явным на сайте вызова, какой аргумент может быть мутирован.
2 - Иногда это убивает производительность. Ссылки и указатели являются ад для компилятора из-за сглаживания. Возьмем следующий код
std::array<double, 2> fval(const std::array<double, 2>& v) {
std::array<double, 2> ans;
ans[0] = cos(v[0] + v[1]);
ans[1] = sin(v[0] + v[1]);
return ans;
}
Тот же код, который принимает as в качестве ссылки, в 2 раза медленнее:
std::array<double, 2> fref(const std::array<double, 2>& v,
std::array<double, 2>& ans) {
ans[0] = cos(v[0] + v[1]);
ans[1] = sin(v[0] + v[1]);
}
Сглаживание указателя не позволяет компилятору вычислять sin и cos с помощью одной машинной команды (Gcc в настоящее время не выполняет эту оптимизацию, но icpc делает оптимизацию с семантикой значений).