Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Value Initialization vs Calloc vs Manual Initialization Speed

Tags:

c++

performance

c

Which is the fastest?

I tried to test the speeds of the three methods in a basic capacity with this:

#include "stdafx.h"
#include "stdlib.h"
#include "stdio.h"
#include "time.h"

int _tmain(int argc, _TCHAR* argv[])
{
  const unsigned long long ARR_SIZ = 0x4fffffff;
  clock_t val_init_dur, calloc_dur, manual_dur;
  clock_t cur = clock();
  char* val_init = new char[ARR_SIZ]();
  clock_t after = clock();
  val_init_dur = after-cur;
  delete[] val_init;

  cur = clock();
  void* calloc_init = calloc(ARR_SIZ, sizeof(char));
  after = clock();
  calloc_dur = after-cur;
  free(calloc_init);

  cur = clock();
  char* manual_init = new char[ARR_SIZ];
  for (unsigned long i=0; i < ARR_SIZ; i++)
    manual_init[i] = 0;
  after = clock();
  manual_dur = after-cur;
  delete[] manual_init;

  printf("Value Initialization Duration: %d\n", val_init_dur);
  printf("Calloc Initialization Duration: %d\n", calloc_dur);
  printf("Manual Initialization Duration: %d\n", manual_dur);
  fgetc(stdin);
  return 0;
}

My results were:

Value Initialization Duration: 541

Calloc Initialization Duration: 493

Manual Initialization Duration: 3424

But I have several issues with my current test:

  • I don't know if I properly isolated the three different methods of initialization
  • I didn't test all methods of initializing an array of zeros (memset and malloc, which I suspect work like calloc)
  • The results are in seconds (ew!) which are horribly quantized. (No ms time?)
  • The value for ARR_SIZ is not the maximum permitted size by VS '12 (0x7FFFFFFF). I was unable to set the value any higher than what is in the code above as I was getting bad_alloc exceptions from the first new call, despite the code compiling.
  • I suspect that there is a faster way to manually initialize an array via iteration than how I did it

I italicized one of the bullet points above because I am very curious as to why that is the case.

Does anyone have advice how to improve my test code? Or even better, does anyone have a straightforward answer to the initial question of which is fastest?

Also: I have turned OFF compiler optimization

Edit: I updated my code to use clock(). Results updated as well.

like image 337
SyntaxTerror Avatar asked Oct 31 '22 19:10

SyntaxTerror


1 Answers

The tests are not equivalent because using calloc and maybe value initialization, does not actually 0 the memory until it is touched. Whereas your manual setting of the malloc'd memory to 0 causes it to be touched and therefore allocated. Try reading each element of the value and calloc'd memory and (assuming optimizer doesn't eliminate read because value not used) you should get the same results.

It does depends on OS. A simpler OS may not do it this way. Often memory is divided into pages. Commonly a page is not actually allocated by the OS until it is touched by the program. It is only "reserved". This is to speed up programs which don't end up using all the memory they allocate. If you remove the code which modifies the malloc'd memory, maybe it will speed up.

To clarify - all this happens behind the scenes by the OS. Your program is totally ok to assume the values are ready at 0 at any time, from the value-initialization and calloc.

Personally I would use vector for all dynamic arrays unless a special case. It will set values to 0 by default.

like image 121
Neil Kirk Avatar answered Nov 15 '22 03:11

Neil Kirk