Skip to content

bpo-38328: Speed up the creation time of constant list literals. #16498

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

Closed
wants to merge 7 commits into from

Conversation

brandtbucher
Copy link
Member

@brandtbucher brandtbucher commented Sep 30, 2019

This PR contains a small change to the peephole optimizer that converts sequences of:

LOAD_CONST(a), LOAD_CONST(b), ..., BUILD_LIST(n)

to

LOAD_CONST((a, b, ...)), BUILD_LIST_UNPACK(1)

The improvement quickly becomes significant for lists larger than a few items:

Elements Speedup
5 ~5%
10 ~20%
15 ~25%
20 ~30%
25 ~35%
30 ~45%
35 ~50%

This can be tested on any version of Python by comparing the performance of [0, 1, 2, ...] vs [*(0, 1, 2, ...)]. The common cases of empty and single-element lists are not affected by this change.

This is related to bpo-33325, but that was an invasive change for all collection literals that had an unknown affect on performance. I've limited this one to lists and kept it to a few lines in the peephole optimizer.

https://bugs.python.org/issue38328

@brandtbucher brandtbucher added the performance Performance or resource usage label Sep 30, 2019
@brandtbucher brandtbucher changed the title boo-38328: Speed up the creation time of constant list literals. bpo-38328: Speed up the creation time of constant list literals. Sep 30, 2019
@@ -1222,7 +1222,7 @@ def get_gen(): yield 1
# list
samples = [[], [1,2,3], ['1', '2', '3']]
for sample in samples:
check(sample, vsize('Pn') + len(sample)*self.P)
check(list(sample), vsize('Pn') + len(sample)*self.P)
Copy link
Member Author

Choose a reason for hiding this comment

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

This is a sys.getsizeof test. The 3-element lists are overallocated, so we resize them here.

@brandtbucher
Copy link
Member Author

@serhiy-storchaka Since you proposed something similar a while back, do you mind taking a look at this when you have the chance?

h, i+1, consts, j);
h, i+1-islist, consts, j);
if (h >= 0 && islist) {
h = copy_op_arg(codestr, i, BUILD_LIST_UNPACK, 1, i+1);
Copy link
Member

Choose a reason for hiding this comment

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

h is not used. Remove h = .

It can also be replaced with

codestr[i] = PACKOPARG(BUILD_LIST_UNPACK, 1);

@brandtbucher
Copy link
Member Author

Thanks for the feedback @serhiy-storchaka. Tests are passing, ready for another review.

@brandtbucher
Copy link
Member Author

Thank @serhiy-storchaka. Is anything else needed here?

@serhiy-storchaka
Copy link
Member

Nothing particular. I just want to fix the issue with list overallocation first. Your PR is good, thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting merge performance Performance or resource usage
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants