Browse Source

replace every call to toupper with one to our own tolower_ascii

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.
debian/1.8.y
David Kalnischkies 12 years ago
parent
commit
6dc60370a7
  1. 8
      apt-pkg/contrib/error.h
  2. 10
      apt-pkg/contrib/macros.h
  3. 49
      apt-pkg/contrib/strutl.cc
  4. 21
      apt-pkg/contrib/strutl.h
  5. 2
      debian/changelog

8
apt-pkg/contrib/error.h

@ -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;};

10
apt-pkg/contrib/macros.h

@ -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
@ -72,17 +74,17 @@
// 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

49
apt-pkg/contrib/strutl.cc

@ -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;
}

21
apt-pkg/contrib/strutl.h

@ -25,19 +25,12 @@
#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

2
debian/changelog

@ -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:

Loading…
Cancel
Save