В настоящее время я изучаю C ++ самостоятельно, и мне любопытно, как push_back()
и emplace_back()
работают под капотом.Я всегда предполагал, что emplace_back()
быстрее, когда вы пытаетесь создать и поместить большой объект в конец контейнера, например, вектор.
Давайте предположим, что у меня есть Student
объект, который яхочу добавить к концу вектора студентов.
struct Student {
string name;
int student_ID;
double GPA;
string favorite_food;
string favorite_prof;
int hours_slept;
int birthyear;
Student(string name_in, int ID_in, double GPA_in, string food_in,
string prof_in, int sleep_in, int birthyear_in) :
/* initialize member variables */ { }
};
Предположим, я вызываю push_back()
и помещаю объект Student
в конец вектора:
vector<Student> vec;
vec.push_back(Student("Bob", 123456, 3.89, "pizza", "Smith", 7, 1997));
Насколько я понимаю, push_back
создает экземпляр объекта Student
вне вектора и затем перемещает его в конец вектора.
Диаграмма:
Я также могу использовать вместо push:
vector<Student> vec;
vec.emplace_back("Bob", 123456, 3.89, "pizza", "Smith", 7, 1997);
Насколько я понимаю, объект Student создается в самом конце вектора, поэтому перемещение не требуется.
Диаграмма:
Таким образом, будет иметь смысл, что развертывание будет быстрее, особенно если будет добавлено много объектов Student.Однако, когда я рассчитал эти две версии кода:
for (int i = 0; i < 10000000; ++i) {
vec.push_back(Student("Bob", 123456, 3.89, "pizza", "Smith", 7, 1997));
}
и
for (int i = 0; i < 10000000; ++i) {
vec.emplace_back("Bob", 123456, 3.89, "pizza", "Smith", 7, 1997);
}
, я ожидал, что последняя будет быстрее, так как большой объект Student не нужно будет перемещать,Как ни странно, версия emplace_back
оказалась медленнее (при нескольких попытках).Я также попытался вставить 10000000 объектов Student, где конструктор получает ссылки, а аргументы в push_back()
и emplace_back()
хранятся в переменных.Это также не сработало, так как emplace был еще медленнее.
Я проверил, чтобы убедиться, что я вставляю одинаковое количество объектов в обоих случаях.Разница во времени не слишком велика, но применение заканчивалось медленнее на несколько секунд.
Что-то не так с моим пониманием того, как работают push_back()
и emplace_back()
?Большое спасибо за ваше время!
Вот код в соответствии с просьбой.Я использую компилятор g ++.
Откат назад:
struct Student {
string name;
int student_ID;
double GPA;
string favorite_food;
string favorite_prof;
int hours_slept;
int birthyear;
Student(string name_in, int ID_in, double GPA_in, string food_in,
string prof_in, int sleep_in, int birthyear_in) :
name(name_in), student_ID(ID_in), GPA(GPA_in),
favorite_food(food_in), favorite_prof(prof_in),
hours_slept(sleep_in), birthyear(birthyear_in) {}
};
int main() {
vector<Student> vec;
vec.reserve(10000000);
for (int i = 0; i < 10000000; ++i)
vec.push_back(Student("Bob", 123456, 3.89, "pizza", "Smith", 7, 1997));
return 0;
}
Возврат:
struct Student {
string name;
int student_ID;
double GPA;
string favorite_food;
string favorite_prof;
int hours_slept;
int birthyear;
Student(string name_in, int ID_in, double GPA_in, string food_in,
string prof_in, int sleep_in, int birthyear_in) :
name(name_in), student_ID(ID_in), GPA(GPA_in),
favorite_food(food_in), favorite_prof(prof_in),
hours_slept(sleep_in), birthyear(birthyear_in) {}
};
int main() {
vector<Student> vec;
vec.reserve(10000000);
for (int i = 0; i < 10000000; ++i)
vec.emplace_back("Bob", 123456, 3.89, "pizza", "Smith", 7, 1997);
return 0;
}