Refactorization: Faster calculation of CRC32 by avoiding to create a temporary string. Use proper types in checksum functions. (#4180)

Merged from LCppC
This commit is contained in:
PKEuS 2022-06-08 16:55:06 +02:00 committed by GitHub
parent 898a3a25a1
commit 4bd189c3c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 16 additions and 18 deletions

View File

@ -1017,30 +1017,28 @@ static const std::uint32_t crc32Table[] = {
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
}; };
static std::uint32_t crc32(const std::string &data) static void crc32(const std::string &data, uint32_t& crc)
{ {
std::uint32_t crc = ~0U;
for (char c : data) { for (char c : data) {
crc = crc32Table[(crc ^ (unsigned char)c) & 0xFF] ^ (crc >> 8); crc = crc32Table[(crc ^ (unsigned char)c) & 0xFF] ^ (crc >> 8);
} }
return crc ^ ~0U;
} }
unsigned int Preprocessor::calculateChecksum(const simplecpp::TokenList &tokens1, const std::string &toolinfo) const uint32_t Preprocessor::calculateChecksum(const simplecpp::TokenList &tokens1, const std::string &toolinfo) const
{ {
std::ostringstream ostr; std::uint32_t crc = ~0U;
ostr << toolinfo << '\n'; crc32(toolinfo, crc);
for (const simplecpp::Token *tok = tokens1.cfront(); tok; tok = tok->next) { for (const simplecpp::Token *tok = tokens1.cfront(); tok; tok = tok->next) {
if (!tok->comment) if (!tok->comment)
ostr << tok->str(); crc32(tok->str(), crc);
} }
for (std::map<std::string, simplecpp::TokenList *>::const_iterator it = mTokenLists.begin(); it != mTokenLists.end(); ++it) { for (std::map<std::string, simplecpp::TokenList *>::const_iterator it = mTokenLists.begin(); it != mTokenLists.end(); ++it) {
for (const simplecpp::Token *tok = it->second->cfront(); tok; tok = tok->next) { for (const simplecpp::Token *tok = it->second->cfront(); tok; tok = tok->next) {
if (!tok->comment) if (!tok->comment)
ostr << tok->str(); crc32(tok->str(), crc);
} }
} }
return crc32(ostr.str()); return crc ^ ~0U;
} }
void Preprocessor::simplifyPragmaAsm(simplecpp::TokenList *tokenList) const void Preprocessor::simplifyPragmaAsm(simplecpp::TokenList *tokenList) const

View File

@ -170,7 +170,7 @@ public:
* @param toolinfo Arbitrary extra toolinfo * @param toolinfo Arbitrary extra toolinfo
* @return CRC32 checksum * @return CRC32 checksum
*/ */
unsigned int calculateChecksum(const simplecpp::TokenList &tokens1, const std::string &toolinfo) const; uint32_t calculateChecksum(const simplecpp::TokenList &tokens1, const std::string &toolinfo) const;
void simplifyPragmaAsm(simplecpp::TokenList *tokenList) const; void simplifyPragmaAsm(simplecpp::TokenList *tokenList) const;

View File

@ -460,20 +460,20 @@ void TokenList::createTokens(simplecpp::TokenList&& tokenList)
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
unsigned long long TokenList::calculateChecksum() const uint64_t TokenList::calculateChecksum() const
{ {
unsigned long long checksum = 0; uint64_t checksum = 0;
for (const Token* tok = front(); tok; tok = tok->next()) { for (const Token* tok = front(); tok; tok = tok->next()) {
const unsigned int subchecksum1 = tok->flags() + tok->varId() + tok->tokType(); const uint32_t subchecksum1 = tok->flags() + tok->varId() + tok->tokType();
unsigned int subchecksum2 = 0; uint32_t subchecksum2 = 0;
for (char i : tok->str()) for (char i : tok->str())
subchecksum2 += (unsigned int)i; subchecksum2 += (uint32_t)i;
if (!tok->originalName().empty()) { if (!tok->originalName().empty()) {
for (char i : tok->originalName()) for (char i : tok->originalName())
subchecksum2 += (unsigned int) i; subchecksum2 += (uint32_t)i;
} }
checksum ^= ((static_cast<unsigned long long>(subchecksum1) << 32) | subchecksum2); checksum ^= ((static_cast<uint64_t>(subchecksum1) << 32) | subchecksum2);
const bool bit1 = (checksum & 1) != 0; const bool bit1 = (checksum & 1) != 0;
checksum >>= 1; checksum >>= 1;

View File

@ -156,7 +156,7 @@ public:
* Calculates a 64-bit checksum of the token list used to compare * Calculates a 64-bit checksum of the token list used to compare
* multiple token lists with each other as quickly as possible. * multiple token lists with each other as quickly as possible.
*/ */
unsigned long long calculateChecksum() const; uint64_t calculateChecksum() const;
/** /**
* Create abstract syntax tree. * Create abstract syntax tree.