я должен взять аргументы подставляемым функциям ссылкой или значением?

используйте $ get и $ lt, чтобы найти данные даты в mongodb

var tomorrowDate = moment(new Date()).add(1, 'days').format("YYYY-MM-DD");
db.collection.find({"plannedDeliveryDate":{ $gte: new Date(tomorrowDate +"T00:00:00.000Z"),$lt: new Date(tomorrowDate + "T23:59:59.999Z")}})
24
задан rlbond 6 April 2009 в 16:44
поделиться

9 ответов

Параметр должен быть набран в соответствии с тем, что имеет смысл для функции.

Если функция принимает примитивный тип, передача по значению будет иметь смысл. Некоторые люди, которых я знаю, будут жаловаться, если они будут переданы const ref (так как это «ненужно»), но я не думаю, что жаловался бы. Если функция принимает пользовательский тип и не изменяет параметр, тогда имеет смысл передавать по const ref.

Если это определенный пользователем тип, а параметр изменен, то семантика функции будет определять, как ее следует передавать.

19
ответ дан Michael Burr 28 November 2019 в 20:43
поделиться

Это не имеет значения. В обоих случаях код будет встроен в то же самое. Излишне копирование int (в передаче по значению) будет исключено компилятором, и ненужное создание ссылки на int и последующий уровень косвенности при доступе к int также будут исключены.

Ваш вопрос, кажется, основан на некоторых ложных предположениях:

  • Что встроенное ключевое слово фактически сделает вашу функцию встроенной. (Возможно, но это, безусловно, не гарантировано).
  • Выбор эталонного значения зависит от действующей функции. (Точно такие же соображения производительности применимы и к не встроенной функции).
  • То, что она имеет значение, и что вы можете перехитрить компилятор с такими тривиальными изменениями (компилятор будет применять одинаковые оптимизации в любом случае )
  • И что оптимизация действительно измерила бы разницу в производительности. (даже если этого не произойдет, разница будет настолько мала, что будет незначительной.)

Я знаю, что целочисленные типы должны передаваться по значению. Тем не менее, я обеспокоен тем, что компилятор может встроить ProcessByValue, чтобы содержать копию. Есть ли для этого правила?

Да, он создаст копию. Также как передача по ссылке создаст ссылку. И тогда, по крайней мере, для простых типов, таких как int, компилятор снова устранит оба. Встраивание функции не может изменить поведение функции. Если вы создаете функцию, принимающую аргумент значения, она будет вести себя так, как если бы ей был задан аргумент значения, независимо от того, встроена она или нет. Если вы определите функцию для получения ссылки, она будет вести себя так, как если бы она передавала ссылку, независимо от того, встроена она или нет. Так что делай то, что ведет к правильному поведению.

26
ответ дан jalf 28 November 2019 в 20:43
поделиться

Компилятор должен иметь возможность оптимизировать встроенную функцию, чтобы любой метод генерировал идентичный код. Сделай тот, который яснее всего.

Если есть сомнения, попробуйте. Включите вывод списка компиляции вашего компилятора и посмотрите, есть ли разница.

7
ответ дан Mark Ransom 28 November 2019 в 20:43
поделиться

Лучший способ понять это - создать испытательный стенд, который выполняет обе задачи, создать оптимизированные версии кода и проверить его на сборке. Вы сразу увидите, что происходит с вашим конкретным компилятором и вашим конкретным вариантом использования.

Когда дело доходит до дела, делайте то, что, по вашему мнению, ожидает пользователь вашего класса от интерфейса. Когда у вас все это построено и работает, измерьте и выясните, где ваши узкие места. Скорее всего, любая разница, которая может это сделать (и вряд ли она что-либо изменит), будет заглушена более серьезными проблемами производительности в других местах вашего кода.

0
ответ дан dma 28 November 2019 в 20:43
поделиться

Передача по значению, если тип меньше или сопоставим с указателем; например, int, char, double, small struct, ...

Передача по ссылке для более крупных объектов; например, контейнеры STL. Я много читал о том, что компиляторы могут оптимизировать его, но в моем простом тесте они этого не сделали. Если вы не хотите тратить время на тестирование вариантов использования, используйте const T& obj.

Бонус: для более быстрой скорости используйте restrict из c99 (таким образом, вы догоняете фортран, который ограничивает наложение указателей; случай использования: f(const T&__restrict__ obj). Стандарт C ++ не допускает ключевое слово restrict, но компиляторы использовать внутренние ключевые слова - g ++ использует __restrict__. Если в коде нет псевдонимов, выигрыш в скорости отсутствует.

тест с g ++ 4.9.2:

Передача вектора по ссылке :

> cat inpoint.cpp
#include <vector>
#include <iostream>

using namespace std;

inline int show_size(const vector<int> &v) {
  return v.size();
}

int main(){
  vector<int> v(100000000);
  cout << show_size(v) << endl;
  return 0;
}
> g++ -std=c++14 -O2 inpoint.cpp; time ./a.out
100000000

real    0m0.330s
user    0m0.072s
sys     0m0.256s

Передача вектора по значению занимает вдвое больше времени:

> cat invalue.cpp
#include <vector>
#include <iostream>

using namespace std;

inline int show_size(vector<int> v) {
  return v.size();
}

int main(){
  vector<int> v(100000000);
  cout << show_size(v) << endl;
  return 0;
}
> g++ -std=c++14 -O2 invalue.cpp; time ./a.out
100000000

real    0m0.985s
user    0m0.204s
sys     0m0.776s
2
ответ дан kirill_igum 28 November 2019 в 20:43
поделиться

Если ваш компилятор не достаточно умен, чтобы оптимизировать локальную копию, которая не была изменена, он, вероятно, недостаточно умен, чтобы оптимизировать локальную ссылку. В этом случае он будет генерировать еще более ужасный код для случая передачи по ссылке (каждый доступ будет косвенным).

0
ответ дан Greg Rogers 28 November 2019 в 20:43
поделиться

Очень короткий ответ: при принятии решения о передаче по ссылке или по значению обрабатывайте встроенные и не встроенные функции одинаково.

0
ответ дан Dima 28 November 2019 в 20:43
поделиться

В случае с примитивами это не имеет значения, потому что вы передаете только 4 байта.

Причиной передачи ссылки является то, что она имеет размер 4 байта, и это значительно уменьшает размер в случае пользовательских типов и больших строк.

Аргумент за скорость ... обычно.

В случае встроенной функции вы бы хотели, чтобы все типы, которые не являются примитивами, передавались по ссылке, так как вы в первую очередь указываете компилятору встроить ее.

0
ответ дан Will 28 November 2019 в 20:43
поделиться

Как правило,

объявляют только выходные примитивы в качестве ссылок.

Объявите входной примитив только как ссылку или const ref, если вам нужно запретить выражения:

int two = plus1( 1 );  //  compile error if plus1 is declared as "int plus1( int& )"

double y = sqrt( 1.1 * 2 );  // compile error if sqrt is declared as "double sqrt( const double& )"
-1
ответ дан axel22 28 November 2019 в 20:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: