> I'm planning to add a set of new performance diagnostics to the
> libstdc++ profile mode
> (http://gcc.gnu.org/onlinedocs/libstdc++/manual/profile_mode.html) and
> am trying to come up with a list of what diagnostics are most
> meaningful and most wanted.
> 
> At this (brainstorming) point I'm looking for any suggestions,
> including and not limited to:
> - container selection (e.g., replace list with deque).
> - container implementation selection (e.g., string implementation).
> - algorithm selection (e.g., sort implementation)
> - data structure or algorithm parameter selection (e.g., fixed string
> reserved size value for a particular context).
> 
> Please reply to this message or email me privately (r...@google.com) if
> you have any suggestions for new diagnostics, or about the profile
> mode in general, or to express your support for a particular proposed
> diagnostic.  For new diagnostics, it works best if you can provide:

First idea, based on a performance issue I fixed in a codebase in 2001:

> - A simple description, e.g., "replace vector with list".

"cache value of std::string::c_str() instead of multiple invocations with a 
non-shareable declared std::string"

> - (optional) The instrumentation points, even if vague, e.g.,
> "instrument insertion, element access and iterators".

Instrument calls to std::string::c_str() that are allocation and invocation 
context-aware.

> - (optional) How the decision is made, e.g. "there are many inserts in
> the middle, there is no random access and it's not iterated through
> many times".

1) allocation of std::string in local variable
2) calls to said local string's c_str() method within loops
3) and said loops do not modify the contents of the value returned from c_str()

Example:

#include <string>
#include <cstdio>

void notify(const char* printable) { printf("%s\n", printable); }

int main(void)
{
  std::string name("bob");
  for (int i = 0; i < name.length(); i++)
  {
    notify(name.c_str());
  }

  return 0;
}


Second idea, based on the same codebase as before. Removing 5 conversions 
to/from std::string and char* resulted in a 10X throughput improvement in 
network throughput in that codebase:

> - A simple description, e.g., "replace vector with list".

"avoid converting a std::string to a char*, just to convert it back to 
std::string later in the call stack"
 
> - (optional) The instrumentation points, even if vague, e.g.,
> "instrument insertion, element access and iterators".

Instrument calls to std::string::c_str(), tracking the resulting value returned 
by c_str().

> - (optional) How the decision is made, e.g. "there are many inserts in
> the middle, there is no random access and it's not iterated through
> many times".

1) where a value is returned by std::string::c_str()
2) and said char* value is fed back into std::string constructor, locally or 
further down the call chain
3) and said char* value was not modified between the calls to 
std::string::c_str() and std::string()

Example:

#include <cstdio>
#include <string>

void tally(const std::string& index) { printf("%s\n", index.c_str()); }

void notify(const char* printable) { tally(std::string(printable)); }

int main(void)
{
  std::string name("bob");
  notify(name.c_str());

  return 0;
}


Over the years, I have seen both of these occur multiple times across multiple 
teams. The constant seems to be C programmers who are passive-aggressive about 
their distaste for STL, and/or teams with poor communication between module 
owners.

Reply via email to