WoW, I didn't know what emplace(_back) function is faster than push(_back)..

I was just testing emplace_back or push_back(vector) or emplace or push (stack) and I got new info(just for me) that when a type of container is an object, emplace function is faster than push function..

when I use push_back avg time: 140~150ms
when I use emplace_back avg time: 79~83ms

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <stack>
#include <vector>
#include <ctime>

using namespace std;

int main()
{
	//stack<string> myStack;
	vector<string> myStack;
	myStack.reserve(50000);
	int sum = 0;

	for (int j = 0; j != 10; ++j)
	{
		clock_t startTime = clock();
		for (int i = 0; i != 50000; ++i)
		{
			//myStack.push("[");
			//myStack.emplace("[");
			myStack.push_back("[");
			//myStack.emplace_back("[");
		}
		clock_t endTime = clock();
		sum += endTime - startTime;
		cout << endTime - startTime << "ms" << endl;
		myStack.clear();
	}
	cout << "average: " << sum / 10 << "ms";


	return 0;
}
Last edited on
cout << endTime - startTime << "ms" << endl;
the unit is not milliseconds
The value returned is expressed in clock ticks, which are units of time of a constant but system-specific length (with a relation of CLOCKS_PER_SEC clock ticks per second).


¿did you compile with optimizations enabled?
@ne555

Really? it's not? why I thought It is milliseconds..

and maybe..? I did not change the VS2019 setting.. If It is a default option.
Last edited on
CLOCKS_PER_SEC is usually at least a million. If it is a million then clock() represents microseconds. You can of course simply print CLOCKS_PER_SEC out and see what it is on your system.

To convert clock() to seconds, just do the following. Note that you need to make sure at least one of the values is floating point so you don't get integer division.

1
2
3
4
    auto start = clock();
    // do something here...
    auto end = clock();
    std::cout << double(end - start) / CLOCKS_PER_SEC << " seconds\n";

However, in C++ it's best to use the chrono library, something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <algorithm>
#include <chrono>
#include <iostream>
#include <string>

template<typename T>
inline void show_time(T start, T end) {
    std::cout << std::chrono::duration_cast<std::chrono::microseconds>
                 (end - start).count() << " microseconds\n";
}

int main() {
    auto clk = std::chrono::high_resolution_clock{};

    auto start = clk.now();
    // do something here...
    show_time(start, clk.now());
}

Last edited on
> However, in C++ it's best to use the chrono library
no, they measure different things
man wrote:
The clock() function returns an approximation of processor time used by the program.

whereas chrono measures real time (aka wall-clock)

for example, if you have cin >> n; your program is blocked until the user ends its inputs
there clock() will not move, but chrono does


also
cppreference wrote:
Notes
The high_resolution_clock is not implemented consistently across different standard library implementations, and its use should be avoided.
(...)
use steady_clock for duration measurements, and system_clock for wall-clock time.
.
Thanks ne555. You're absolutely right. I should've known better since I have heard that before, although I had never heard about the problem with high_resolution_clock.

Here's a program demonstrating the difference between clock and steady_clock.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <chrono>
#include <ctime>

template<typename T>
inline void show_time(T start, T end) {
    std::cout << std::chrono::duration_cast<std::chrono::microseconds>
                 (end - start).count() << " microseconds\n";
}

inline void print_time(clock_t start, clock_t end) {
    std::cout << double(end - start) / CLOCKS_PER_SEC * 1000000 << " microseconds\n";
}

int main() {
    auto clk = std::chrono::steady_clock{};

    auto start1 = clock();
    auto start2 = clk.now();

    std::cout << "Wait a few seconds, then press Enter.\n";
    std::cin.get();

    print_time(start1, clock());
    show_time(start2, clk.now());
}

I was just testing emplace_back or push_back(vector) or emplace or push (stack) and I got new info(just for me) that when a type of container is an object, emplace function is faster than push function.

You're on the right track.

An emplace function (-template) is occasionally much faster, rarely slower, occasionally cleaner, and sometimes more error-prone than the corresponding push function.

The performance difference is most significant for types that are expensive to move as compared to push_back. For example, given a type T that is expensive to move, ts.push_back(T(arg1, arg2, arg3)) would be significantly worse than ts.emplace_back(arg1, arg2, arg3).

In the case you presented, emplace_back avoids a move from the materialized temporary std::string bound to the reference parameter of push_back. Moving std::string is a very cheap (almost free) operation. For very short strings like the ones you're working with, constructing the std::string is just as cheap thanks to small-buffer optimization inside std::string. This is why the emplace_back version is essentially twice as fast.
Last edited on
Topic archived. No new replies allowed.