3 분 소요

개요

기존의 vectorC스타일의 배열과 호환성이 좋았으나, 요소 추가/삭제등이 필요하여 동적 메모리를 사용하다 보니, 메모리 할당시 을 사용합니다. 이 때문에 아무래도 메모리 할당 측면에서는 스택에 할당되는 C스타일의 배열보다 성능이 떨어졌습니다.

C++11 부터는 array가 추가되어 기존 C스타일의 배열처럼 연속된 메모리를 사용하는 컨테이너를 제공합니다. C스타일 배열처럼 컴파일 타임에 크기가 결정되어 스택에 할당되므로, 에 할당되는 vector 보다 성능이 좋습니다.

항목 설명 C스타일 배열 array vector
연속된 메모리 모두 연속된 메모리를 사용합니다. O O O
동적 메모리 할당 C스타일 배열array는 컴타일 타임에 크기가 결정되어 스택에 할당됩니다. X X O
요소 추가/삭제 C스타일 배열array는 요소를 추가/삭제할 수 없습니다. X X O
요소 접근 [] 인덱스 범위 검사를 하지 않습니다. O O O
요소 접근 at() 인덱스 범위 검사를 합니다. X O O
이터레이터 arrayvector는 순방향 및 역방향 탐색을 지원합니다. X O O
배열 주소 데이터의 첫번째 요소의 주소를 구할 수 있습니다. arr 또는 arr[0] arr.data() &v[0]
포인터로의 암시적 변환 C스타일 배열int* p = arr; 와 같이 포인터로 암시적 변환 됩니다.
오버로딩된 함수 결정 규칙에 따라 함수 인자C스타일 배열 사용시 포인터로 취급됩니다.
O X X
중괄호 초기화를 통한 요소 갯수 유추 배열은 초기화 요소의 갯수로 C스타일 배열의 요소 갯수를 유추하지만, array는 명시적으로 지정해야 합니다. O X O
중괄호 초기화를 통한 자동 제로 초기화 요소의 갯수보다 적게 초기화하면 나머지 요소는 0으로 초기화 됩니다. O O O
속도 C스타일 배열array스택에 할당되기 때문에, 에 할당되는 vector보다 빠릅니다. 1 2 3
대입 C스타일 배열은 대입을 지원하지 않으며, array는 요소의 갯수가 같으면 대입됩니다. X O O
1
2
3
4
5
6
7
8
9
10
11
12
std::array<int, 3> a{1, 2, 3};
std::array<int, 3> b{4, 5}; 
std::array<int, 2> c{4, 5};   

// int* ptr = a; // (X) 컴파일 오류. array는 포인터로 암시적 변환이 되지 않습니다.
int* ptr = a.data(); // data를 이용하면 포인터로 변환됩니다.  

EXPECT_TRUE(b[0] == 4 && b[1] == 5 && b[2] == 0); // 요소의 갯수보다 적게 초기화하면 나머지 요소는 0으로 초기화 됩니다.

// c = a; // (X) 컴파일 오류. 요소의 갯수가 다르면 컴파일 오류가 발생합니다.
b = a; // 요소의 갯수가 같으면 대입이 가능합니다.
EXPECT_TRUE(b[0] == 1 && b[1] == 2 && b[2] == 3);

array 멤버 함수

항목 내용
at() (C++11~) (작성중)
front() (C++11~) (작성중)
back() (C++11~) (작성중)
data() (C++11~) 컨테이너가 관리하는 메모리 블록을 리턴합니다.
begin(), end() (C++11~) (작성중)
cbegin(), cend() (C++11~) (작성중)
rbegin(), rend() (C++11~) (작성중)
crbegin(), crend() (C++11~) (작성중)
empty() (C++11~) (작성중)
size() (C++11~) (작성중)
max_size() (C++11~) (작성중)
fill() (C++11~) (작성중)
swap() (C++11~) (작성중)
== (C++11~)
!= (C++11~C++20)
(작성중)
<, <=, >, >= (C++11~C++20)
<=> (C++20~)
(작성중)
to_array() (C++20~) 기존 C스타일 배열로부터 array를 생성합니다.

배열, array, vector 속도 비교

다음은 C스타일 배열, array, vector의 생성/소멸과 접근 속도를 테스트한 예입니다. 시간 측정을 위해 chrono 라이브러리를 사용했습니다.

  1. 십만개의 요소를 십만번 생성/소멸했고,
  2. 십만개의 요소에 접근하여 값을 대입합니다.
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// 생성/소멸 테스트
void CStyleArrayConstruct() {
    for(int i{0}; i < 100000; ++i) {
        int arr[100000];
    }        
}
void STLArrayConstruct() {
    for(int i{0}; i < 100000; ++i) {
        std::array<int, 100000> arr;
    }        
}
void STLVectorConstruct() {
    for(int i{0}; i < 100000; ++i) {
        std::vector<int> arr(100000);
    }        
}      
// 접근 테스트
void CStyleArrayAccess() {
    int arr[100000];

    for(int i{0}; i < 100000; ++i) {
        arr[i] = i;
    }        
}
void STLArrayAccess() {
    std::array<int, 100000> arr;

    for(int i{0}; i < 100000; ++i) {
        arr[i] = i;
    }        
}
    void STLVectorAccess() {
    std::vector<int> arr(100000);

    for(int i{0}; i < 100000; ++i) {
        arr[i] = i;
    }        
}  

template<typename Func>
std::chrono::microseconds Measure(Func f) {
    std::chrono::system_clock::time_point start{std::chrono::system_clock::now()};    

    f();

    std::chrono::system_clock::time_point end{std::chrono::system_clock::now()};
    std::chrono::microseconds val{std::chrono::duration_cast<std::chrono::microseconds>(end - start)};

    return val;
}

// 생성/소멸 테스트
std::cout << "CStyleArray : " << Measure(CStyleArrayConstruct).count() << std::endl;
std::cout << "STLArray : " << Measure(STLArrayConstruct).count() << std::endl;
std::cout << "STLVector : " << Measure(STLVectorConstruct).count() << std::endl;

// 접근 테스트
std::cout << "CStyleArray : " << Measure(CStyleArrayAccess).count() << std::endl;
std::cout << "STLArray : " << Measure(STLArrayAccess).count() << std::endl;
std::cout << "STLVector : " << Measure(STLVectorAccess).count() << std::endl;

실행 결과는 다음과 같습니다. array가 생성/소멸이 C스타일 배열 보다 빠른게 좀 의외이긴 합니다.

1
2
3
4
5
6
7
CStyleArray : 660
STLArray : 228 // C스타일 배열보다 빠릅니다.
STLVector : 18612352 // 동적 할당을 하다보니 느립니다.

CStyleArray : 209
STLArray : 404 // operator[]을 이용하다 보니 C스타일 배열보다는 느립니다.
STLVector : 487 // operator[]을 이용하다 보니 C스타일 배열보다는 느립니다.

태그:

카테고리:

업데이트:

댓글남기기