Bug 1426770 - [perf] Big performance regression between 0.6.3-6 and 0.6.4-6.2
Summary: [perf] Big performance regression between 0.6.3-6 and 0.6.4-6.2
Keywords:
Status: CLOSED RAWHIDE
Alias: None
Product: Fedora
Classification: Fedora
Component: hawkey
Version: 25
Hardware: Unspecified
OS: Unspecified
high
unspecified
Target Milestone: ---
Assignee: Jaroslav Mracek
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2017-02-24 19:43 UTC by Michael Simacek
Modified: 2017-04-03 12:05 UTC (History)
7 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed: 2017-04-03 12:05:18 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)

Description Michael Simacek 2017-02-24 19:43:36 UTC
Description of problem:
In koschei we observe big performance regression in resolution using hawkey after upgrading the machine from f24 to f25. Our resolution task suddenly started to take half an hour. We run hawkey goal with installations, one goal per-package. I reproduced the problem locally with reduced package set (so reduced number of iterations, in order to not wait half an hour).
hawkey-0.6.3-6.fc25.x86_64: 32s
hawkey-0.6.3-6.2.fc25.x86_64: 2 minutes

Suspected upstream commit (thanks mizdebsk for pointing to it): https://github.com/rpm-software-management/hawkey/commit/9b90fa2335edf74775184c88c5423b5f5a6ab204

Comment 1 Michael Simacek 2017-02-24 20:33:13 UTC
Reproducer:
sack = get a sack for fedora 26 repo somehow

brs=['perl', 'perl(AnyEvent)', 'perl(AnyEvent::Handle)', 'perl(AnyEvent::Socket)', 'perl(Authen::SASL)', 'perl(Data::Dumper)', 'perl(Digest::SHA)', 'perl(Encode)', 'perl(Exporter)', 'perl(ExtUtils::MakeMaker)', 'perl(IO::Handle)', 'perl(MIME::Base64)', 'perl(Net::LibIDN)', 'perl(Object::Event)', 'perl(Scalar::Util)', 'perl(Test::More)', 'perl(Time::Local)', 'perl(XML::Parser::Expat)', 'perl(XML::Twig)', 'perl(XML::Writer)', 'perl(base)', 'perl(constant)', 'perl(overload)', 'perl(strict)', 'perl(warnings)', 'perl-generators']

for i in range(100):
    goal = hawkey.Goal(sack)
    for br in brs:
        goal.install(provides=br)
    goal.run()
    goal.list_installs()


This finishes under 1 second with -6, but needs ~10 seconds with -6.2

Comment 2 Honza Silhan 2017-02-27 15:06:26 UTC
Now it considers the obsoletes too, but could be made faster (by adding API for setting multiple provides?)

Comment 3 Michael Simacek 2017-02-28 17:24:20 UTC
Could this be given more priority? I understand it's not important for regular users, but it causes production problems for koschei. Our repo and build processing now lags behind what happens in koji, resulting in poor user experience for our users (when they get a notification about a broken build they need to wait for the dependency difference report).
And I can imagine that releng/qa tools that bulk process packages might be affected too.

Comment 4 Honza Silhan 2017-03-03 18:12:14 UTC
can you please include code snippet or link what are you doing in Koshei with Selector.set(provides=...)?

Do you need the selector to find the package obsoleting provide name or just any package providing given Provide?

Comment 5 Michael Simacek 2017-03-07 15:30:11 UTC
(In reply to Honza Silhan from comment #4)
> can you please include code snippet or link what are you doing in Koshei
> with Selector.set(provides=...)?
>

Our code for handling selectors consist of helper functions which were taken directly from dnf code [1] (the reason for bundling the code is that koschei backend used to be deployed on RHEL, where dnf wasn't available at that time)

> Do you need the selector to find the package obsoleting provide name or just
> any package providing given Provide?

We need to simulate installation of package BuildRequires the same way as it happens in koji (mock). We need to do the same thing as dnf builddep would do. So the answer to your question depends on whether dnf builddep needs it (I don't know that at the moment).

[1] https://github.com/msimacek/koschei/blob/master/koschei/backend/depsolve.py#L28

Comment 6 Honza Silhan 2017-03-07 15:46:51 UTC
Hmm, so you are basically duplicating DNF code which has significantly changed recently in DNF.

If you get dependencies just from spec file then it is still unnecessary complex (_nevra_to_selector, etc.). Can you please try:
```
q = hawkey.Query(sack).filter(provides=dep)
s = sltr.set(one_of=q)
```
instead of:
`s = sltr.set(provides=dep)`


and report whether this approach is faster?
(this is current approach in DNF BTW)

Comment 7 Michael Simacek 2017-03-07 17:56:28 UTC
(In reply to Honza Silhan from comment #6)
> Hmm, so you are basically duplicating DNF code which has significantly
> changed recently in DNF.
> 
> If you get dependencies just from spec file then it is still unnecessary
> complex (_nevra_to_selector, etc.). Can you please try:
> ```
> q = hawkey.Query(sack).filter(provides=dep)
> s = sltr.set(one_of=q)
> ```
> instead of:
> `s = sltr.set(provides=dep)`
> 
> 
> and report whether this approach is faster?
> (this is current approach in DNF BTW)

There's no one_of argument in f25's hawkey. I tried doing goal.install(q.run()[0]), which takes ~4 seconds in my test. Which is an improvement from 10 s, but still regression from mere miliseconds.

I also tried using dnf's Subject.get_best_selector in rawhide and got the same ~ 4s.

Comment 8 Jaroslav Mracek 2017-03-10 13:46:48 UTC
We try to fix the problem by reverting patch that introduce handling obsoletes for provide transactions (https://github.com/rpm-software-management/libdnf/pull/275), but we cannot back port it to fedora25, because it will reintroduce bug about obsoletes.

Comment 9 Jaroslav Mracek 2017-04-03 12:05:18 UTC
The patch was released into rawhide in libdnf-0.8.1-1


Note You need to log in before you can comment on or make changes to this bug.