Home > Back-end >  What's the difference between std::vector and dynamic allocated array?
What's the difference between std::vector and dynamic allocated array?

Time:03-01

I have wrote two functions to compare the time cost of std::vector and dynamic allocated array

#include <iostream>
#include <vector>
#include <chrono>

void A() {
  auto t1 = std::chrono::high_resolution_clock::now();
  std::vector<float> data(5000000);
  auto t2 = std::chrono::high_resolution_clock::now();

  float *p = data.data();
  for (int i = 0; i < 5000000;   i) {
    p[i] = 0.0f;
  }
  auto t3 = std::chrono::high_resolution_clock::now();
  std::cout << std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count() << " us\n";
  std::cout << std::chrono::duration_cast<std::chrono::microseconds>(t3 - t2).count() << " us\n";
}

void B() {
  auto t1 = std::chrono::high_resolution_clock::now();
  auto* data = new float [5000000];
  auto t2 = std::chrono::high_resolution_clock::now();
  float *ptr = data;
  for (int i = 0; i < 5000000;   i) {
    ptr[i] = 0.0f;
  }
  auto t3 = std::chrono::high_resolution_clock::now();
  std::cout << std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count() << " us\n";
  std::cout << std::chrono::duration_cast<std::chrono::microseconds>(t3 - t2).count() << " us\n";
}

int main(int argc, char** argv) {
  A();
  B();
  return 0;
}

A() cost about 6000 us to initialize the vector, then 1400 us to fill zeros.

B() cost less than 10 us to allocate memory, then 5800 us to fill zeros.

Why their time costs have such a large difference?

compiler: g =9.3.0

flags: -O3 -DNDEBUG

CodePudding user response:

First, note that the std::vector<float> constructor already zeros the vector.

There are many plausible system-level explanations for the behavior you observe:

One very plausible is caching: When you allocate the array using new, the memory referenced by the returned pointer is not in the cache. When you create a vector, the constructor will zero the allocated memory area under the hood thereby bringing the memory to the cache. Subsequent zeroing will hit in the cache thus.

Other reasons might include compiler optimizations. A compiler might realize that your zeroing is unneccesary with std::vector. Given the figures you obtained I would discount this here though.

CodePudding user response:

QuickBench is a nice tool to compare different ways doing the same thing. QuickBench results

All variants but the push_back one are almost the same in runtime. But the vector is much safer. It's very easy to forget to free the memory (as you demonstrated yourself).

EDIT: Fixed the mistake in the push_back variant. Thanks to t.niese and Scheff's Cat for pointing it out and fixing it.

CodePudding user response:

First things first. You immediately demonstrate why we use RAII types like std::vector: you call new, but never call delete. I.e. you have a memory leak. Maybe you say "but this is just a demonstration". Well, memory leaks are an actual big problem in C and C , and have lead to many many issues in production code.

Secondly, your example doesn't make much sense.

std::vector<float> data(N);

will initialize all values to 0.0f

Similar

auto data = new float[N]();

can default initialize all values to 0.0f.

  •  Tags:  
  • c
  • Related