[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: sprezzos apt-show-rewrite complete (report + numbers)



On Wed, Mar 20, 2013 at 06:31:11AM -0400, nick black wrote:
> This is a followup to my post to debian-devel, debian-derivatives, deity,
> and sprezzos-dev last Monday entitled "apt-show-versions rewrite". This
> post is strictly informative, and does not advocate any policy.
> 
> Documentation has been substantially embeefened, including design notes:
> 
>  https://www.sprezzatech.com/wiki/index.php/Raptorial 
>  https://github.com/dankamongmen/raptorial
> 
> rapt-show-versions(1), part of the RAPTORIAL suite, has become
> feature-equivalent to the native apt-show-versions(1) tool, as predicted.
> Despite fleshing out the features, I've managed to retain its speed.

[...]

> Pretty constant performance from both. Let's call it 1.17s vs .13s on the
> quadcore and 1.12s vs .16s on the dualcore (this perhaps surprising result
> can be explained by the fact that there are fewer packages installed on the
> dualcore).
> 
> **** Quadcore winner: RAPTORIAL at 11% running time
> **** Dualcore winner: RAPTORIAL at 11% running time
> **** Champion: RAPTORIAL with a ~90% reduction in time
> 
> Oh btw, if you don't take it to /dev/null, RAPTORIAL beats apt-show-versions
> by several seconds. It is absolutely faster across the board.
> 
> Gentlemen, you claimed that you could "whip up a C++ apt-show-versions" and
> get similar performance. Consider the gauntlet thrown, and the mic dropped.
> I look forward to your results.
> 

$ env time ./usr/bin/apt-show-versions > /dev/null
0.02user 0.01system 0:00.04elapsed 76%CPU (0avgtext+0avgdata 20856maxresident)k
0inputs+0outputs (0major+7165minor)pagefaults 0swaps

I currently have 0.04 - 0.05 seconds for my prototype using apt-pkg, including
policy and configuration handling, which you do not have. The tool completely
works from the APT cache like the other tools, and can thus skip parsing
altogether. apt-show-versions takes 1.2 seconds.

The code is attached; it takes some further work to add some missing
functionality (not that much though, just different output format,
and configuration parsing). Output is also not sorted currently.

I'll try to get this finished and merged into APT for jessie.

-- 
Julian Andres Klode  - Debian Developer, Ubuntu Member

See http://wiki.debian.org/JulianAndresKlode and http://jak-linux.org/.
/* apt-show-versions.cc - apt-show-versions for APT
 *
 * Copyright (C) 2011-2013 Julian Andres Klode <jak@debian.org>
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation files
 * (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <apt-pkg/init.h>
#include <apt-pkg/cachefile.h>
#include <apt-pkg/version.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <set>

std::string my_name(pkgCache::PkgIterator p, pkgCache::VerIterator c)
{
    auto name = p.FullName(true);

    for (auto vf = c.FileList(); c.IsGood(); c++) {
        if (vf.File().Codename())
            return name + "/" + vf.File().Codename();
        if (vf.File().Archive())
            return name + "/" + vf.File().Archive();
    }
    return name;
}

bool has_older(pkgCache::PkgIterator p)
{
    pkgCache::VerIterator current = p.CurrentVer();
    

    for (auto other = p.VersionList(); other.IsGood(); other++)
        if (other->ID != current->ID && _system->VS->CmpVersion(current.VerStr(), other.VerStr()) > 0)
            return true;

    return false;
}

pkgCache::VerIterator find_newest(pkgCache::PkgIterator p)
{
    pkgCache::VerIterator newest = p.CurrentVer();
    
    for (auto other = p.VersionList(); other.IsGood(); other++)
        if (_system->VS->CmpVersion(newest.VerStr(), other.VerStr()) < 0)
            newest = other;

    return newest;
}

int main(void)
{
    pkgInitConfig(*_config);
    pkgInitSystem(*_config, _system);
    pkgCacheFile cachefile;
    pkgCache *cache = cachefile.GetPkgCache();
    pkgPolicy *depcache = cachefile.GetPolicy();


    if (cache == NULL) {
        _error->DumpErrors();
        return 1;
    }

    for (auto p = cache->PkgBegin(); p != cache->PkgEnd(); p++) {
        if (p->CurrentVer == 0)
            continue;

        auto current = p.CurrentVer();
        auto candidate = depcache->GetCandidateVer(p);
        auto newer = find_newest(p);

        if (p.VersionList()->NextVer == 0 && current.FileList()->NextFile == 0) {
            std::cout << p.FullName(true) << " " << current.VerStr() << " installed: No available version in archive\n";
        } else if (candidate->ID != current->ID) {
            std::cout << my_name(p, candidate) << " upgradable from " << current.VerStr() << " to " << candidate.VerStr() << "\n";
        } else if (current.FileList()->NextFile != 0) {
            /* Still installable */
            std::cout << my_name(p, candidate) << " uptodate " << current.VerStr() << "\n";
        } else if (newer.IsGood() && newer->ID != current->ID) {
            /* Not installable version, but newer exists */
            std::cout << my_name(p, candidate) << " *manually* upgradable from " << current.VerStr() << " to " << newer.VerStr() << "\n";
        } else if (has_older(p)) {
            /* Not installable version, but older exists */
            std::cout << my_name(p, candidate) << " " << current.VerStr() << " newer than version in archive\n";
        }
    }

}

Reply to: