diff options
author | David Kalnischkies <david@kalnischkies.de> | 2014-06-11 20:42:16 +0200 |
---|---|---|
committer | David Kalnischkies <david@kalnischkies.de> | 2014-06-18 12:41:11 +0200 |
commit | e8a7b0b28ca01cd8c2c1bee0d83e5997b40de689 (patch) | |
tree | becaf02ebbdd39d5415747af58d7e0fd42ce02e0 /apt-pkg/pkgcache.cc | |
parent | 8d20b69d2fd7a8fec82bb559f0e39059bbaecf1b (diff) |
increase hashtable size for packages/groups by factor 5
It also makes the size configureable, so it can be adapted in the future
without the need for an abi break - and even by users…
The increase was long overdue as it gives a >10% decrease in runtime of
e.g. 'apt-get check -s'. Some (useless) benchmark with 69933 groups and
187796 packages without a pre-built cache:
time apt-get check -so APT::Cache-HashTableSize=1 → 20m
time apt-get check -so APT::Cache-HashTableSize=1000 → 6,41s
time apt-get check -so APT::Cache-HashTableSize=2000 → 5,64s (old)
time apt-get check -so APT::Cache-HashTableSize=3000 → 5,30s
time apt-get check -so APT::Cache-HashTableSize=5000 → 5,08s
time apt-get check -so APT::Cache-HashTableSize=6000 → 5,05s
time apt-get check -so APT::Cache-HashTableSize=7000 → 5,02s
time apt-get check -so APT::Cache-HashTableSize=8000 → 5,00s
time apt-get check -so APT::Cache-HashTableSize=9000 → 4,98s
time apt-get check -so APT::Cache-HashTableSize=10000 → 4,96s (new)
time apt-get check -so APT::Cache-HashTableSize=15000 → 4,90s
time apt-get check -so APT::Cache-HashTableSize=20000 → 4,86s
time apt-get check -so APT::Cache-HashTableSize=30000 → 4,77s
time apt-get check -so APT::Cache-HashTableSize=40000 → 4,74s
time apt-get check -so APT::Cache-HashTableSize=50000 → 4,73s
time apt-get check -so APT::Cache-HashTableSize=60000 → 4,71s
The gap increases further for operations which have more package
lookups. Factor 5 was chosen as higher values do not provide any
really significant timing advantage anymore compared to the memory
increase in my testing and there is always the possibility to increase
it now if that changes. (also most users will not have 3 releases and
4 architectures in the cache, so theirs will be much smaller and faster).
Diffstat (limited to 'apt-pkg/pkgcache.cc')
-rw-r--r-- | apt-pkg/pkgcache.cc | 23 |
1 files changed, 11 insertions, 12 deletions
diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc index 4fbdc93d5..7b092f07e 100644 --- a/apt-pkg/pkgcache.cc +++ b/apt-pkg/pkgcache.cc @@ -54,8 +54,8 @@ pkgCache::Header::Header() /* Whenever the structures change the major version should be bumped, whenever the generator changes the minor version should be bumped. */ - MajorVersion = 9; - MinorVersion = 2; + MajorVersion = 10; + MinorVersion = 0; Dirty = false; HeaderSz = sizeof(pkgCache::Header); @@ -85,8 +85,7 @@ pkgCache::Header::Header() StringList = 0; VerSysName = 0; Architecture = 0; - memset(PkgHashTable,0,sizeof(PkgHashTable)); - memset(GrpHashTable,0,sizeof(GrpHashTable)); + HashTableSize = _config->FindI("APT::Cache-HashTableSize", 10 * 1048); memset(Pools,0,sizeof(Pools)); CacheFileSize = 0; @@ -194,7 +193,7 @@ unsigned long pkgCache::sHash(const string &Str) const unsigned long Hash = 0; for (string::const_iterator I = Str.begin(); I != Str.end(); ++I) Hash = 41 * Hash + tolower_ascii(*I); - return Hash % _count(HeaderP->PkgHashTable); + return Hash % HeaderP->HashTableSize; } unsigned long pkgCache::sHash(const char *Str) const @@ -202,7 +201,7 @@ unsigned long pkgCache::sHash(const char *Str) const unsigned long Hash = tolower_ascii(*Str); for (const char *I = Str + 1; *I != 0; ++I) Hash = 41 * Hash + tolower_ascii(*I); - return Hash % _count(HeaderP->PkgHashTable); + return Hash % HeaderP->HashTableSize; } /*}}}*/ // Cache::SingleArchFindPkg - Locate a package by name /*{{{*/ @@ -213,7 +212,7 @@ unsigned long pkgCache::sHash(const char *Str) const pkgCache::PkgIterator pkgCache::SingleArchFindPkg(const string &Name) { // Look at the hash bucket - Package *Pkg = PkgP + HeaderP->PkgHashTable[Hash(Name)]; + Package *Pkg = PkgP + HeaderP->PkgHashTable()[Hash(Name)]; for (; Pkg != PkgP; Pkg = PkgP + Pkg->Next) { if (unlikely(Pkg->Name == 0)) @@ -278,7 +277,7 @@ pkgCache::GrpIterator pkgCache::FindGrp(const string &Name) { return GrpIterator(*this,0); // Look at the hash bucket for the group - Group *Grp = GrpP + HeaderP->GrpHashTable[sHash(Name)]; + Group *Grp = GrpP + HeaderP->GrpHashTable()[sHash(Name)]; for (; Grp != GrpP; Grp = GrpP + Grp->Next) { if (unlikely(Grp->Name == 0)) continue; @@ -432,10 +431,10 @@ void pkgCache::GrpIterator::operator ++(int) S = Owner->GrpP + S->Next; // Follow the hash table - while (S == Owner->GrpP && (HashIndex+1) < (signed)_count(Owner->HeaderP->GrpHashTable)) + while (S == Owner->GrpP && (HashIndex+1) < (signed)Owner->HeaderP->HashTableSize) { HashIndex++; - S = Owner->GrpP + Owner->HeaderP->GrpHashTable[HashIndex]; + S = Owner->GrpP + Owner->HeaderP->GrpHashTable()[HashIndex]; } } /*}}}*/ @@ -449,10 +448,10 @@ void pkgCache::PkgIterator::operator ++(int) S = Owner->PkgP + S->Next; // Follow the hash table - while (S == Owner->PkgP && (HashIndex+1) < (signed)_count(Owner->HeaderP->PkgHashTable)) + while (S == Owner->PkgP && (HashIndex+1) < (signed)Owner->HeaderP->HashTableSize) { HashIndex++; - S = Owner->PkgP + Owner->HeaderP->PkgHashTable[HashIndex]; + S = Owner->PkgP + Owner->HeaderP->PkgHashTable()[HashIndex]; } } /*}}}*/ |