컴퓨터 공학/C++

[C++] vector 컨테이너 반복문 종류별 성능

혼새미로 2019. 11. 14. 13:00
반응형

vector 컨테이너에 대한 반복문을 수행하는 방법은 1) 범위 기반 for 문, 2) 인덱스 접근 for 문, 3) 데이터 배열 취득 후 인덱스 접근 for문, 4) 반복자 사용 for 문 있다. 각각의 방식에 대한 성능이 궁금해져서 각 방식에 대한 성능을 측정해보기로 하였다.

데이터 크기만큼 int형 원소를 갖는 vector를 생성한 후 각 방식대로 반복문을 수행하면서 각 원소에 1이라는 값을 대입하였다.

데이터 크기를 1024, 2048, 4096, ..., 16777216 과 같이 1024부터 두 배씩 증가하여 각 방식의 성능을 측정하였며, 이 작업을 열 번 반복하여 평균을 내었다. 

​ 소스코드는 다음과 같다.

 

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
#include <iomanip>
#include "HourMeter.h"
using namespace std;
void main() {
	ofstream writeFile("./result.txt");
	if (writeFile.is_open() == false) {
		printf("File open failed\n");
		return;
	}
	constexpr int NUM_SIZE_UP = 15;
	constexpr int NUM_REPEAT = 10;
	HourMeter hm;
	/* INFO: 같은 작업 반복 */
	for (int j = 0; j < NUM_REPEAT; j++) {
		int dataSize = 1024;
		stringstream ss;
		ss.clear();
		/* INFO: 데이터 크기를 2배씩 증가한다. */
		for (int i = 0; i < NUM_SIZE_UP; i++) {
			printf("j: %d, i: %d, dataSize: %d\n", j, i, dataSize);
			/* INFO: 범위 기반 for 문 */
			{
				vector<int> arr;
				arr.resize(dataSize);
				hm.startMeasure();
				for (auto& value : arr) {
					value = 1;
				}
				hm.endMeasure();
				ss << to_string(hm.getLatestDuration()) << ", ";
			}
			/* INFO: 인덱스 접근 for 문 */
			{
				vector<int> arr;
				arr.resize(dataSize);
				hm.startMeasure();
				for (int i = 0, size = arr.size(); i < size; i++) {
					arr[i] = 1;
				}
				hm.endMeasure();
				ss << to_string(hm.getLatestDuration()) << ", ";
			}
			/* INFO: 데이터 배열 획득 후 인덱스 접근 for 문 */
			{
				vector<int> arr;
				arr.resize(dataSize);
				auto arrPtr = arr.data();
				hm.startMeasure();
				for (int i = 0, size = arr.size(); i < size; i++) {
					arrPtr[i] = 1;
				}
				hm.endMeasure();
				ss << to_string(hm.getLatestDuration()) << ", ";
			}
			/* INFO: 반복자 for 문 */
			{
				vector<int> arr;
				arr.resize(dataSize);
				hm.startMeasure();
				for (auto iter = arr.begin(), end = arr.end(); iter != end; iter++) {
					*iter = 1;
				}
				hm.endMeasure();
				ss << to_string(hm.getLatestDuration()) << endl;
			}
			dataSize <<= 1;
		}
		writeFile << ss.str() << endl;
	}
	writeFile.close();
}

 

실험 결과는 다음과 같다.
* RB-for: 범위 기반 for 문
* IDX-for: 인덱스 접근 for 문
* DIDX-for: 데이터 배열 획득 후 인덱스 접근 for 문
* ITER-for: 반복자 사용 for 문

결론
* vector에서 반복문을 수행할 때 범위 기반 for 문이 인덱스 접근 for문 보다 빠르다.
* 범위 기반 for문과 데이터 배열 획득 후 인덱스 접근 for문과 거의 동일한 성능을 보인다.
* 반복자 사용 for 문은 사용하지 않는 것이 좋다.
* 가능하면 컨테이너 사용 시 범위 기반 for 문을 사용하는 것이 성능에 이롭다.

실험 자료는 첨부하였다.

컨테이너+반복문+속도+측정+실험.xlsx
0.02MB

반응형