Evaluate/Access Once, Read multiple times

Evaluate/Access Once, Read multiple times

29 May 2018    

In certain cases, when accessing certain class / struct members, it can be costly if you’re reading the member multiple times. Especially in cases with branches the compiler may not store the object in a register i.e. it will not evaluate the access once.

Take this case for example:

void SomeFunction(DataRecord const& dr) {
  if (dr.row.Id() == RecordId) {
      // do something
  }
  else if (dr.row.Type() == RecordType) {
      // do something else
  }
  else {
      dr.layer.SetProperties(RecordProperties);
  }
}

In the example above, dr.layer is being accessed multiple times. Another rather short/contrived example here: https://godbolt.org/g/og2E72

To not only make the code a bit simpler but also possibly a bit more effecient, try to access and store the layer into a local object like so:

  auto const& row = dr.row;
  auto const& rowId = row.Id();

  // and use row from here onwards

This can be even more costly if it is accessed via a getter dr.row()! While in most cases the compiler does a good job of not creating extra moves, using this method will not result in worse code gen.

Lastly, this is even more pertinent when dealing with data structures and associated algorithms. Instead of doing multiple look ups, always prefer to lookup once and dereference the iterator:

if (table.at(key) == Key) {
  // ...
}

object.EnableAttribute(table.at(key)); //second lookup, avoid

Instead just deref the iterator using auto& data = *table.at(key); and use that instead.