Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve performance of API calls #1538 #1547

Merged
merged 6 commits into from
Aug 12, 2024
Merged

Conversation

pombredanne
Copy link
Collaborator

@pombredanne pombredanne commented Aug 12, 2024

This PR tries to improve the API lookup calls.

One hotspot is the the Package.is_vulnerable property that runs an exists() on a queryset
in a repeated manner.

To avoid this, the approach is to annotate the Package queryset(s) with an is_vulnerable
attribute.

The results with a single API call to http://127.0.0.1:8001/api/packages/63 are like this
using pyinstrument and django-toolbar on a laptop:

Before

  • pyinstrument:
Absolute time
Duration: 1.46 seconds
Samples: 1376
CPU time: 1.3 seconds
  • django-toolbar:
Time
Resource 	Value
User CPU time 	3992.892 msec
System CPU time 	69.885 msec
Total CPU time 	4062.777 msec
Elapsed time 	4162.812 msec
Context switches 	13364 voluntary, 52 involuntary

SQL
224.49 ms (1329 queries including 1327 similar and 1299 duplicates ) 

The pyinstrument hotspot are calls to:

Package.is_vulnerable
vulnerabilities/models.py:647

After:

  • pyinstrument:
Absolute time
Duration: 0.288 seconds
Samples: 276
CPU time: 0.263 seconds
  • django-toolbar:
Time
Resource 	Value
User CPU time 	395.396 msec
System CPU time 	20.186 msec
Total CPU time 	415.582 msec
Elapsed time 	439.888 msec
Context switches 	2588 voluntary, 17 involuntary

SQL
83.03 ms (99 queries including 96 similar and 68 duplicates ) 

Or an improvement looking like this:

tool old new improvement
pyinstrument 1.46 s 0.288 s x 5.06
toolbar 4.16 s 0.439 s x 9.47

Reference:#1538
Signed-off-by: Philippe Ombredanne pombredanne@nexb.com

Reference:#1538
Signed-off-by: Philippe Ombredanne <pombredanne@nexb.com>
Remove unused imports
Move univers monkey patching to top level

Reference:#1538
Signed-off-by: Philippe Ombredanne <pombredanne@nexb.com>
* is_vulnerable is now a queryset annotation.
* with_is_vulnerable Package manager method annotates the queryset
* It is now called anywhere needed.

The results with a single API call to
http://127.0.0.1:8001/api/packages/63 are:
* before 1.7 sec
* after  0.25 sec

Or an improvement where the old is 6.8 times slower than the new.

Reference:#1538
Signed-off-by: Philippe Ombredanne <pombredanne@nexb.com>
* simplify sorting code, revert to using lists
* use cached_property where relevant

Reference:#1538
Signed-off-by: Philippe Ombredanne <pombredanne@nexb.com>
* Fix how we find vulnerable and non vulnerable versions
* Complete using is_vulnerable in relevant querysets.
* Adjust tests for clarity and DRY using small method to make the tests
  setup easier to read
* Use proper typing annotation for PackageURL or str
* Add new Package manager from_purl() method to create a Package from
  a PURL

Reference:#1538
Signed-off-by: Philippe Ombredanne <pombredanne@nexb.com>
Signed-off-by: Philippe Ombredanne <pombredanne@nexb.com>
Copy link
Contributor

@TG1999 TG1999 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@TG1999 TG1999 merged commit 457f8f8 into main Aug 12, 2024
11 checks passed
@pombredanne pombredanne deleted the performance-improvements branch August 16, 2024 08:06
@TG1999 TG1999 added the 0-next label Aug 27, 2024
@pombredanne pombredanne added 1-next and removed 0-next labels Sep 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging this pull request may close these issues.

2 participants