DEV Community

mahesh_attarde
mahesh_attarde

Posted on

[DopeTales] String operation slowdown in Source Generator Streams

Compilers tends to manipulate readable strings way to much than any other software. Source generators written decade ago and six months back dont really have than much difference. Here is attempt to improve that.

Source Generators tend to build strings by concatenating strings. Usual go to solution for this problem is Attempt 1

Attempt 1

std::string oBuffer;
oBuffer.append("ContextPrefix");
oBuffer.append("_");
oBuffer.append(pClassName.c_str());
Stream<<oBuffer.c_str();
Enter fullscreen mode Exit fullscreen mode

This solution creates different string in memory, results in memory allocations,resizing etc. moreover tend to slow down whole software stack.
Concatenating string with "+" operator does no good either.

Attempt 2

StringBuffer  sBuffer;
sBuffer.append("ContextPrefix");
sBuffer.append("_");
sBuffer.append(pClassName.c_str());
Stream<<sBuffer.c_str();
Enter fullscreen mode Exit fullscreen mode

This solution was inspired by Java/CSharp followup and sadly help from Stackoverflow. While Cpp does not support this, writing own implementation of StringBuffer give much more flexibility of optimizing whole operation. Still we will end up separate buffer.

Attempt 3

typedef std::pair<const char *,const char *> PrefixString;
inline std::ostream& operator<< (std::ostream& pOut,PrefixString& pPair){
    pOut<<pPair.first<<"_"<<pPair.second;
    return pOut;
}
/*Using PrefixString in Source Generator code */
void SourceWriter::ClassBegin(const char * pQualifiedName){
    PrefixString oStr =  std::make_pair(Constants::ContextPrefix,pQualifiedName);
    mOut << oStr;
}
Enter fullscreen mode Exit fullscreen mode

Third attempt is made considering fact that strings are always present in objects.
We need not have separate buffer to create output string. In example shown above,
PrefixString is pair which is just placeholder for char string pointers. It can directly write Prefix String without any intermediate buffer. moreover operator << is inlined. Most of runtime decisions are moved to compile time. and Hence faster alternative.

Hope this helps.

Top comments (0)