[lld] r314192 - Speed up SymbolTable::insert().

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 25 21:17:13 PDT 2017


Author: ruiu
Date: Mon Sep 25 21:17:13 2017
New Revision: 314192

URL: http://llvm.org/viewvc/llvm-project?rev=314192&view=rev
Log:
Speed up SymbolTable::insert().

SymbolTable::insert() is a hot path function. When linking a clang debug
build, the function is called 3.7 million times. The total amount of "Name"
string contents is 300 MiB. That means this `Name.find("@@")` scans almost
300 MiB of data. That's far from negligible.

StringRef::find(StringRef) uses a sophisticated algorithm, but the
function is slow for a short needle. This patch replaces it with
StringRef::find(char).

This patch alone speeds up a clang debug build link time by 0.5 seconds
from 8.2s to 7.7s. That's 6% speed up. It seems too good for this tiny
change, but looks like it's real.

Modified:
    lld/trunk/ELF/SymbolTable.cpp

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=314192&r1=314191&r2=314192&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Mon Sep 25 21:17:13 2017
@@ -206,8 +206,12 @@ static uint8_t getMinVisibility(uint8_t
 std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) {
   // <name>@@<version> means the symbol is the default version. In that
   // case <name>@@<version> will be used to resolve references to <name>.
-  size_t Pos = Name.find("@@");
-  if (Pos != StringRef::npos)
+  //
+  // Since this is a hot path, the following string search code is
+  // optimized for speed. StringRef::find(char) is much faster than
+  // StringRef::find(StringRef).
+  size_t Pos = Name.find('@');
+  if (Pos != StringRef::npos && Pos + 1 < Name.size() && Name[Pos + 1] == '@')
     Name = Name.take_front(Pos);
 
   auto P = Symtab.insert(




More information about the llvm-commits mailing list