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

bpo-34100: compile: Re-enable frozenset merging #10760

Merged
merged 4 commits into from
Nov 28, 2018

Conversation

methane
Copy link
Member

@methane methane commented Nov 28, 2018

Py_INCREF(t);
Py_DECREF(key);
return t;
}

// We registered o in c_const_cache.
// When o is a tuple or frozenset, we want to merge it's
// items too.
Copy link
Member

Choose a reason for hiding this comment

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

Would it be possible to do it backward?

  • First merge items
  • Then merge the container

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it just make program more complicated. We need to check the container is not registered yet before merging items. So we need to generate key tuple containing the container object first anyway.

Copy link
Member

Choose a reason for hiding this comment

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

Would it be possible to add the newly merged container to the cache rather than modifying the existing cache entry in-place?

Copy link
Member Author

Choose a reason for hiding this comment

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

It's possible. This commit rewrites tuple merging without in-place modify of tuple and key.
2eb1471

But I'm not sure avoiding in-place edit is so important...
We have similar code already.
https://github.com/python/cpython/blob/master/Objects/codeobject.c#L47-L95

Copy link
Member

Choose a reason for hiding this comment

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

https://github.com/python/cpython/blob/master/Objects/codeobject.c#L47-L95

Oh wow, this code is even worse: it modify the "immutable" arguments of PyCode_New() :-(

@vstinner
Copy link
Member

I wrote an implementation of my proposal (merge items, then the container): PR #10762.

@methane
Copy link
Member Author

methane commented Nov 28, 2018

I wrote an implementation of my proposal (merge items, then the container): PR #10762.

When there are 100 same 5-tuples, my PR makes key objects 100+5 times. In your PR, key object
is created 100*5 times.

@vstinner
Copy link
Member

Travis CI is unhappy:

======================================================================
FAIL: test_singletons (test.test_ast.ConstantTests) (const=frozenset())
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/travis/build/python/cpython/Lib/test/test_ast.py", line 1164, in test_singletons
    self.assertIs(value, const)
AssertionError: frozenset() is not frozenset()

@vstinner
Copy link
Member

When there are 100 same 5-tuples, my PR makes key objects 100+5 times. In your PR, key object is created 100*5 times.

I wrote PR #10762 for the correctness more than for performance :-) Is it possible to measure the overhead of merge_consts_recursive() with a benchmark?

cc @serhiy-storchaka

@methane
Copy link
Member Author

methane commented Nov 28, 2018

I wrote PR #10762 for the correctness more than for performance :-) Is it possible to measure the overhead of merge_consts_recursive() with a benchmark?

$ ./python.victor -m perf timeit --compare-to ./python.master 'compile("[" + "((1., 2.), (3., 4., 5.)),"*100 + "]", "", "exec")'
python.master: ..................... 770 us +- 34 us
python.victor: ..................... 857 us +- 35 us

Mean +- std dev: [python.master] 770 us +- 34 us -> [python.victor] 857 us +- 35 us: 1.11x slower (+11%)

Performance difference is relatively small because parser is slower than compiler.

@vstinner
Copy link
Member

Oh thanks for the benchmark. Would you mind to run the benchmark on your PR as well?

@methane
Copy link
Member Author

methane commented Nov 28, 2018

Oh thanks for the benchmark. Would you mind to run the benchmark on your PR as well?

This benchmark measures only tuples and floats. So my PR (only affects frozenset) doesn't have overhead.

$  ./python -m perf timeit --compare-to ./python.master 'compile("[" + "((1., 2.), (3., 4., 5.)),"*100 + "]", "", "exec")'
python.master: ..................... 772 us +- 35 us
python: ..................... 763 us +- 37 us

Mean +- std dev: [python.master] 772 us +- 35 us -> [python] 763 us +- 37 us: 1.01x faster (-1%)
Not significant!

@methane
Copy link
Member Author

methane commented Nov 28, 2018

And when I removed merge_const_recursive:

$ ./python -m perf timeit --compare-to ./python.master 'compile("[" + "((1., 2.), (3., 4., 5.)),"*100 + "]", "", "exec")'
python.master: ..................... 774 us +- 37 us
python: ..................... 744 us +- 36 us

Mean +- std dev: [python.master] 774 us +- 37 us -> [python] 744 us +- 36 us: 1.04x faster (-4%)

$ git diff
diff --git a/Python/compile.c b/Python/compile.c
index 45e78cb22c..5f6247e9a1 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -1302,7 +1302,8 @@ merge_consts_recursive(struct compiler *c, PyObject *o)
 static Py_ssize_t
 compiler_add_const(struct compiler *c, PyObject *o)
 {
-    PyObject *key = merge_consts_recursive(c, o);
+    //PyObject *key = merge_consts_recursive(c, o);
+    PyObject *key = _PyCode_ConstantKey(o);
     if (key == NULL) {
         return -1;
     }

Copy link
Member

@vstinner vstinner left a comment

Choose a reason for hiding this comment

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

LGTM. "./python -m test test_compile -R 3:3" pass.

I have no strong preference between your PR and my PR, as soon as the tests pass :-)

@vstinner vstinner merged commit f7e4d36 into python:master Nov 28, 2018
@methane methane deleted the merge-const2 branch November 29, 2018 07:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants