0

What's a fast way to fill a union/struct of integral members with ALL Zeroes?

RECORD* UNION = {0};

void ZeroStruct(int X, int Y)
{
    UNION = new RECORD[X * Y];
    int K = 0;

    for (int I = 0; I < X; I++)
        for (int J = 0; J < Y; J++)
        {
            UNION[K].X = 0;
            UNION[K].Y = 0;
            UNION[K].Z = 0;
            UNION[K].Magnitude = 0;
            UNION[K].Direction = 0;
            UNION[K].Angle = 0;
            ++K;                
        }
}

It's not slow but I want to know what's a faster way as depending on user input, X and Y can be very large and this method may or may not take long. Also with this method, I have to set each member of the union to 0.

Edited by triumphost

2
Contributors
1
Reply
5
Views
5 Years
Discussion Span
Last Post by mike_2000_17
1

Did it occur to you that you can test this out very easily? When it comes to performance, the only thing that can settle the argument is test results, the rest is just speculative non-sense. Try this:

#include <iostream>
#include <ctime>
#include <algorithm>
#include <cstring>
#include <iomanip>

union Record {
  struct {
    double x,y,z;
  };
  struct {
    double Magnitude, Direction, Angle;
  };
};

using namespace std;

int main() {

  const int X = 10000;
  const int Y = 10000;

  Record* p_records = new Record[X * Y];

  int k = 0;
  clock_t t_start = clock();
  for(int i = 0; i < X; ++i) {
    for(int j = 0; j < Y; ++j) {
      p_records[k].x = 0;
      p_records[k].y = 0;
      p_records[k].z = 0;
      ++k;
    };
  };
  clock_t t_end = clock();
  cout << "First method took: \t" << setw(10) << (t_end - t_start) << " clocks." << endl;

  t_start = clock();
  for(int i = 0; i < X * Y; ++i) {
    p_records[i].x = 0;
    p_records[i].y = 0;
    p_records[i].z = 0;
  };
  t_end = clock();
  cout << "Second method took: \t" << setw(10) << (t_end - t_start) << " clocks." << endl;

  t_start = clock();
  Record* end_records = p_records + X * Y;
  for(Record* p = p_records; p != end_records; ++p) {
    p->x = 0;
    p->y = 0;
    p->z = 0;
  };
  t_end = clock();
  cout << "Third method took: \t" << setw(10) << (t_end - t_start) << " clocks." << endl;

  t_start = clock();
  Record zero_rec;
  zero_rec.x = 0;
  zero_rec.y = 0;
  zero_rec.z = 0;
  fill(p_records, end_records, zero_rec);
  t_end = clock();
  cout << "Fourth method took: \t" << setw(10) << (t_end - t_start) << " clocks." << endl;

  t_start = clock();
  memset((unsigned char*)p_records, 0, X * Y * sizeof(Record));
  t_end = clock();
  cout << "Fifth method took: \t" << setw(10) << (t_end - t_start) << " clocks." << endl;

  delete[] p_records;
  return 0;
};

I get the following output:

First method took:          800000 clocks.
Second method took:         260000 clocks.
Third method took:          260000 clocks.
Fourth method took:         260000 clocks.
Fifth method took:          160000 clocks.

Usually, the std::fill function is the best bet in the C++-friendly options. But, as you see it is pretty much the same as a pointer-based for-loop. If you just want to set all bytes to 0, then the memset function is the best option, but remember that this won't work fro C++ classes in general, only simple struct of primitive types (i.e., a POD-type).

Edited by mike_2000_17: updated results

This question has already been answered. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.