]> git.saurik.com Git - apt.git/commitdiff
replace every call to toupper with one to our own tolower_ascii
authorDavid Kalnischkies <kalnischkies@gmail.com>
Tue, 30 Mar 2010 10:38:38 +0000 (12:38 +0200)
committerDavid Kalnischkies <kalnischkies@gmail.com>
Tue, 30 Mar 2010 10:38:38 +0000 (12:38 +0200)
This sounds like a premature optimization and since Mr. Knuth we all
know that they are the root of all evil - but, and here it starts to be
interesting: As the tolower_ascii method is by far the most called
method we have (~60 Mio. times) and as we compare only strings containing
ascii characters (package names, configuration options) using our own
method reduces execution time of APT by 4% plus it avoids that the
locale settings can influence us.

apt-pkg/contrib/error.h
apt-pkg/contrib/macros.h
apt-pkg/contrib/strutl.cc
apt-pkg/contrib/strutl.h
debian/changelog

index 90747ff7ef0dbc885b2bacaf7c4e35a3a7c300ae..8d5ec05eaaa2e538ec502866033fdadf8b2483f4 100644 (file)
@@ -60,13 +60,13 @@ class GlobalError
    public:
 
    // Call to generate an error from a library call.
-   bool Errno(const char *Function,const char *Description,...) __like_printf_2 __cold;
-   bool WarningE(const char *Function,const char *Description,...) __like_printf_2 __cold;
+   bool Errno(const char *Function,const char *Description,...) __like_printf(3) __cold;
+   bool WarningE(const char *Function,const char *Description,...) __like_printf(3) __cold;
 
    /* A warning should be considered less severe than an error, and may be
       ignored by the client. */
-   bool Error(const char *Description,...) __like_printf_1 __cold;
-   bool Warning(const char *Description,...) __like_printf_1 __cold;
+   bool Error(const char *Description,...) __like_printf(2) __cold;
+   bool Warning(const char *Description,...) __like_printf(2) __cold;
 
    // Simple accessors
    inline bool PendingError() {return PendingFlag;};
index c39caf198dfe12a8875fc5bd7558978dd7d073e1..62e7b65db1d748ae4861ec9c43a4f74da253b471 100644 (file)
@@ -58,6 +58,7 @@
 #if __GNUC__ >= 3
        #define __must_check    __attribute__ ((warn_unused_result))
        #define __deprecated    __attribute__ ((deprecated))
+       #define __attrib_const  __attribute__ ((__const__))
        /* likely() and unlikely() can be used to mark boolean expressions
           as (not) likely true which will help the compiler to optimise */
        #define likely(x)       __builtin_expect (!!(x), 1)
@@ -65,6 +66,7 @@
 #else
        #define __must_check    /* no warn_unused_result */
        #define __deprecated    /* no deprecated */
+       #define __attrib_const  /* no const attribute */
        #define likely(x)       (x)
        #define unlikely(x)     (x)
 #endif
 // cold functions are unlikely() to be called
 #if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4
        #define __cold  __attribute__ ((__cold__))
+       #define __hot   __attribute__ ((__hot__))
 #else
        #define __cold  /* no cold marker */
+       #define __hot   /* no hot marker */
 #endif
 
 #ifdef __GNUG__
 // Methods have a hidden this parameter that is visible to this attribute
-       #define __like_printf_1 __attribute__ ((format (printf, 2, 3)))
-       #define __like_printf_2 __attribute__ ((format (printf, 3, 4)))
+       #define __like_printf(n)        __attribute__((format(printf, n, n + 1)))
 #else
-       #define __like_printf_1 /* no like-printf */
-       #define __like_printf_2 /* no like-printf */
+       #define __like_printf(n)        /* no like-printf */
 #endif
 
 #endif
index 1b9922a31528d18ec5f0ccf6b45c8a1462e6b118..ab47cdede0d93abeb305f1c2c8f3438de24af2c7 100644 (file)
@@ -566,7 +566,7 @@ int stringcmp(string::const_iterator A,string::const_iterator AEnd,
 int stringcasecmp(const char *A,const char *AEnd,const char *B,const char *BEnd)
 {
    for (; A != AEnd && B != BEnd; A++, B++)
-      if (toupper(*A) != toupper(*B))
+      if (tolower_ascii(*A) != tolower_ascii(*B))
         break;
 
    if (A == AEnd && B == BEnd)
@@ -575,7 +575,7 @@ int stringcasecmp(const char *A,const char *AEnd,const char *B,const char *BEnd)
       return 1;
    if (B == BEnd)
       return -1;
-   if (toupper(*A) < toupper(*B))
+   if (tolower_ascii(*A) < tolower_ascii(*B))
       return -1;
    return 1;
 }
@@ -584,7 +584,7 @@ int stringcasecmp(string::const_iterator A,string::const_iterator AEnd,
                  const char *B,const char *BEnd)
 {
    for (; A != AEnd && B != BEnd; A++, B++)
-      if (toupper(*A) != toupper(*B))
+      if (tolower_ascii(*A) != tolower_ascii(*B))
         break;
 
    if (A == AEnd && B == BEnd)
@@ -593,7 +593,7 @@ int stringcasecmp(string::const_iterator A,string::const_iterator AEnd,
       return 1;
    if (B == BEnd)
       return -1;
-   if (toupper(*A) < toupper(*B))
+   if (tolower_ascii(*A) < tolower_ascii(*B))
       return -1;
    return 1;
 }
@@ -601,7 +601,7 @@ int stringcasecmp(string::const_iterator A,string::const_iterator AEnd,
                  string::const_iterator B,string::const_iterator BEnd)
 {
    for (; A != AEnd && B != BEnd; A++, B++)
-      if (toupper(*A) != toupper(*B))
+      if (tolower_ascii(*A) != tolower_ascii(*B))
         break;
 
    if (A == AEnd && B == BEnd)
@@ -610,7 +610,7 @@ int stringcasecmp(string::const_iterator A,string::const_iterator AEnd,
       return 1;
    if (B == BEnd)
       return -1;
-   if (toupper(*A) < toupper(*B))
+   if (tolower_ascii(*A) < tolower_ascii(*B))
       return -1;
    return 1;
 }
@@ -789,28 +789,28 @@ bool ReadMessages(int Fd, vector<string> &List)
 // MonthConv - Converts a month string into a number                   /*{{{*/
 // ---------------------------------------------------------------------
 /* This was lifted from the boa webserver which lifted it from 'wn-v1.07'
-   Made it a bit more robust with a few touppers though. */
+   Made it a bit more robust with a few tolower_ascii though. */
 static int MonthConv(char *Month)
 {
-   switch (toupper(*Month)) 
+   switch (tolower_ascii(*Month)) 
    {
-      case 'A':
-      return toupper(Month[1]) == 'P'?3:7;
-      case 'D':
+      case 'a':
+      return tolower_ascii(Month[1]) == 'p'?3:7;
+      case 'd':
       return 11;
-      case 'F':
+      case 'f':
       return 1;
-      case 'J':
-      if (toupper(Month[1]) == 'A')
+      case 'j':
+      if (tolower_ascii(Month[1]) == 'a')
         return 0;
-      return toupper(Month[2]) == 'N'?5:6;
-      case 'M':
-      return toupper(Month[2]) == 'R'?2:4;
-      case 'N':
+      return tolower_ascii(Month[2]) == 'n'?5:6;
+      case 'm':
+      return tolower_ascii(Month[2]) == 'r'?2:4;
+      case 'n':
       return 10;
-      case 'O':
+      case 'o':
       return 9;
-      case 'S':
+      case 's':
       return 8;
 
       // Pretend it is January..
@@ -1133,10 +1133,13 @@ char *safe_snprintf(char *Buffer,char *End,const char *Format,...)
 
 // tolower_ascii - tolower() function that ignores the locale          /*{{{*/
 // ---------------------------------------------------------------------
-/* */
-int tolower_ascii(int c)
+/* This little function is the most called method we have and tries
+   therefore to do the absolut minimum - and is noteable faster than
+   standard tolower/toupper and as a bonus avoids problems with different
+   locales - we only operate on ascii chars anyway. */
+int tolower_ascii(int const c)
 {
-   if (c >= 'A' and c <= 'Z')
+   if (c >= 'A' && c <= 'Z')
       return c + 32;
    return c;
 }
index e72288f4c5c4ffab704c9bd0b60cef3f5a9c94e2..cdf78f317773e4b14ce7c4039bbd0e2643e718f9 100644 (file)
 #include <iostream>
 #include <time.h>
 
+#include "macros.h"
+
 using std::string;
 using std::vector;
 using std::ostream;
 
-#ifdef __GNUG__
-// Methods have a hidden this parameter that is visible to this attribute
-#define APT_FORMAT2 __attribute__ ((format (printf, 2, 3)))
-#define APT_FORMAT3 __attribute__ ((format (printf, 3, 4)))
-#else
-#define APT_FORMAT2
-#define APT_FORMAT3
-#endif    
-
 bool UTF8ToCodeset(const char *codeset, const string &orig, string *dest);
 char *_strstrip(char *String);
 char *_strtabexpand(char *String,size_t Len);
@@ -60,11 +53,11 @@ bool Hex2Num(const string &Str,unsigned char *Num,unsigned int Length);
 bool TokSplitString(char Tok,char *Input,char **List,
                    unsigned long ListMax);
 vector<string> ExplodeString(string const &haystack, char const &split);
-void ioprintf(ostream &out,const char *format,...) APT_FORMAT2;
-void strprintf(string &out,const char *format,...) APT_FORMAT2;
-char *safe_snprintf(char *Buffer,char *End,const char *Format,...) APT_FORMAT3;
+void ioprintf(ostream &out,const char *format,...) __like_printf(2);
+void strprintf(string &out,const char *format,...) __like_printf(2);
+char *safe_snprintf(char *Buffer,char *End,const char *Format,...) __like_printf(3);
 bool CheckDomainList(const string &Host, const string &List);
-int tolower_ascii(int c);
+int tolower_ascii(int const c) __attrib_const __hot;
 
 #define APT_MKSTRCMP(name,func) \
 inline int name(const char *A,const char *B) {return func(A,A+strlen(A),B,B+strlen(B));}; \
@@ -144,6 +137,4 @@ struct RxChoiceList
 unsigned long RegexChoice(RxChoiceList *Rxs,const char **ListBegin,
                      const char **ListEnd);
 
-#undef APT_FORMAT2
-
 #endif
index 17affee4fc0628ead9fafc8fc6db8ed90f98094d..bd1fda31695b6baffb91febc103bc451b05a34c7 100644 (file)
@@ -60,6 +60,8 @@ apt (0.7.26) UNRELEASED; urgency=low
   * doc/po/de.po:
     - correct a few typos in the german manpage translation.
       Thanks to Chris Leick and Georg Koppen! (Closes: #574962)
+  * apt-pkg/contrib/strutl.cc:
+    - convert all toupper calls to tolower_ascii for a little speedup
 
   [ Julian Andres Klode ]
   * cmdline/apt-mark: