Quellcode durchsuchen

Optimize VersionHash() to not need temporary copy of input

Stop copying stuff, and just parse the bytes one by-one to the
newly created AddCRC16Byte. This improves the instruction count
for an update run from 720,850,121 to 455,801,749 according to
callgrind.
Julian Andres Klode vor 9 Jahren
Ursprung
Commit
f903069c13
3 geänderte Dateien mit 11 neuen und 14 gelöschten Zeilen
  1. 4 0
      apt-pkg/contrib/crc-16.cc
  2. 1 0
      apt-pkg/contrib/crc-16.h
  3. 6 14
      apt-pkg/deb/deblistparser.cc

+ 4 - 0
apt-pkg/contrib/crc-16.cc

@@ -64,6 +64,10 @@ static unsigned short const crc16_table[256] =
 
 
 /* Recompute the FCS with one more character appended. */
 /* Recompute the FCS with one more character appended. */
 #define CalcFCS(fcs, c) (((fcs) >> 8) ^ crc16_table[((fcs) ^ (c)) & 0xff])
 #define CalcFCS(fcs, c) (((fcs) >> 8) ^ crc16_table[((fcs) ^ (c)) & 0xff])
+unsigned short AddCRC16Byte(unsigned short fcs, unsigned char byte)
+{
+   return CalcFCS(fcs, byte);
+}
 unsigned short AddCRC16(unsigned short fcs, void const *Buf,
 unsigned short AddCRC16(unsigned short fcs, void const *Buf,
 			unsigned long long len)
 			unsigned long long len)
 {
 {

+ 1 - 0
apt-pkg/contrib/crc-16.h

@@ -13,6 +13,7 @@
 #include <apt-pkg/macros.h>
 #include <apt-pkg/macros.h>
 
 
 #define INIT_FCS  0xffff
 #define INIT_FCS  0xffff
+unsigned short AddCRC16Byte(unsigned short fcs, unsigned char byte) APT_CONST;
 unsigned short AddCRC16(unsigned short fcs, void const *buf,
 unsigned short AddCRC16(unsigned short fcs, void const *buf,
 			unsigned long long len) APT_PURE;
 			unsigned long long len) APT_PURE;
 
 

+ 6 - 14
apt-pkg/deb/deblistparser.cc

@@ -353,7 +353,6 @@ unsigned short debListParser::VersionHash()
       pkgTagSection::Key::Breaks,
       pkgTagSection::Key::Breaks,
       pkgTagSection::Key::Replaces};
       pkgTagSection::Key::Replaces};
    unsigned long Result = INIT_FCS;
    unsigned long Result = INIT_FCS;
-   char S[1024];
    for (auto I : Sections)
    for (auto I : Sections)
    {
    {
       const char *Start;
       const char *Start;
@@ -363,23 +362,16 @@ unsigned short debListParser::VersionHash()
       
       
       /* Strip out any spaces from the text, this undoes dpkgs reformatting
       /* Strip out any spaces from the text, this undoes dpkgs reformatting
          of certain fields. dpkg also has the rather interesting notion of
          of certain fields. dpkg also has the rather interesting notion of
-         reformatting depends operators < -> <= */
-      char *J = S;
-      for (; Start != End && (J - S) < sizeof(S); ++Start)
+         reformatting depends operators < -> <=, so we drop all = from the
+	 string to make that not matter. */
+      for (; Start != End; ++Start)
       {
       {
-	 if (isspace_ascii(*Start) != 0)
+	 if (isspace_ascii(*Start) != 0 || *Start == '=')
 	    continue;
 	    continue;
-	 *J++ = tolower_ascii_unsafe(*Start);
-
-	 /* Normalize <= to < and >= to >. This is the wrong way around, but
-	  * more efficient that the right way. And since we're only hashing
-	  * it does not matter which way we normalize. */
-	 if ((*Start == '<' || *Start == '>') && Start[1] == '=') {
-	    Start++;
-	 }
+	 Result = AddCRC16Byte(Result, tolower_ascii_unsafe(*Start));
       }
       }
 
 
-      Result = AddCRC16(Result,S,J - S);
+
    }
    }
    
    
    return Result;
    return Result;