FAT Python (lack of) performance
Hi, Summary: FAT Python is not faster, but it will be ;-) -- When I started the FAT Python as a fork of CPython 3.6, I put everything in the same repository. Last weeks, I focused on splitting my giant patch (10k lines) into small reviewable patches. I wrote 3 PEP (509 dict version, 510 function specialziation, 511 code tranformers) and I enhanced the API to make it usable for more use cases than just FAT Python. I also created fatoptimizer (the AST optimizer) and fat (runtime dependency of the optimizer) projects on GitHub to separate clearly what should be outside Python core. For all links, see: http://faster-cpython.readthedocs.org/fat_python.html For the fatoptimizer project, my constraint is to be able to run the full Python test suite unmodified. In practice, I have to disable some optimizations by putting a "__fatoptimizer__= {...}" configuration to some test files. For example, I have to disable constant folding on test_bool because it tests that False+2 gives 2 at runtime, whereas the optimizer replaces directly False+2 with 2 during the compilation. Well, test_bool.py is not the best example because all tests pass with the constant folding optimization (if I comment my "__fatoptimizer__={...}" change). This constraint ensures that the optimizer "works" and doesn't break (too much ;-)) the Python semantics, but it's more difficult to implement powerful optimizations. I also found and fixed various kinds of bugs. In my code obviously, but also in the Python core, in various places. Some bugs only concern AST transformers which is a new feature, but I had to fix them. For example, Python didn't support negative line number delta in co_lntotab of code objects, and so line number were all wrong on optimized code. I merged my enhancement in the default branch of CPython (issue #26107). In short, I focused on having something working (respecting the Python semantics), rather than spending time on writing optimizations. -- When I asked explicitly "Is someone opposed to this PEP 509 [dict verion] ?", Barry Warsaw answered that a performance analysis is required. Extract of his mail: "I still think this is maintenance and potential performance overhead we don't want to commit to long term unless it enables significant optimization. Since you probably can't prove that without some experimentation, this API should be provisional." Last week, I ran some benchmarks and I have to admin that I was disappointed. Not only fatoptimizer doesn't make Python faster, but it makes it much slower on some tests! http://fatoptimizer.readthedocs.org/en/latest/benchmarks.html Quickly, I identified a major performance issue when nested functions are specialized, especially in Lib/json/encoder.py (tested by bm_json_v2.py benchmark). I fixed my optimizer to not specialize nested functions anymore. This simple change fixed the main performance issue. Reminder: in performance critical code, don't use nested functions! I will maybe propose patches for Lib/json/encoder.py to stop using nested functions. I only ran benchmarks with the optimizer enabled. I now have to measure the overhead of my patches (PEP 509, 510 and 511) adding the API fat AST optimizers. The overhead must be negligible. For me, it's a requirement of the whole project. Changes must not make Python slower when the optimizer is not used. fatoptimizer is faster on microbenchmarks, but I had to write manually some optimizations: http://fatoptimizer.readthedocs.org/en/latest/microbenchmarks.html IMHO fatoptimizer is not faster on macro benchmarks because it is not smart enough (yet) to generate the most interesting optimizations, like function inlining and specialization for argument types. You can estimate the speedup if you specialize manually your functions. -- Barry also wrote: "Did you address my suggestion on python-ideas to make the new C API optionally compiled in?" Well, it is an option, but I would prefer to have the API for AST optimizer directly built in Python. The first beta version of Python 3.6 is scheduled in September 2016 (deadline for new features in Python 3.6), so I still have a few months to implement more powerful optimizations and prove that it can be faster ;-) Victor
Hi,
Just thanks for this big contribution.
And maybe this project could give new ideas to optimize Python, who knows ?
At least, you've win a beer for the FOSDEM event this week-end ;-)
Have a nice week.
--
Ludovic Gasc (GMLudo)
http://www.gmludo.eu/
2016-01-25 19:16 GMT+01:00 Victor Stinner
Hi,
Summary: FAT Python is not faster, but it will be ;-)
--
When I started the FAT Python as a fork of CPython 3.6, I put everything in the same repository. Last weeks, I focused on splitting my giant patch (10k lines) into small reviewable patches. I wrote 3 PEP (509 dict version, 510 function specialziation, 511 code tranformers) and I enhanced the API to make it usable for more use cases than just FAT Python. I also created fatoptimizer (the AST optimizer) and fat (runtime dependency of the optimizer) projects on GitHub to separate clearly what should be outside Python core. For all links, see:
http://faster-cpython.readthedocs.org/fat_python.html
For the fatoptimizer project, my constraint is to be able to run the full Python test suite unmodified. In practice, I have to disable some optimizations by putting a "__fatoptimizer__= {...}" configuration to some test files. For example, I have to disable constant folding on test_bool because it tests that False+2 gives 2 at runtime, whereas the optimizer replaces directly False+2 with 2 during the compilation. Well, test_bool.py is not the best example because all tests pass with the constant folding optimization (if I comment my "__fatoptimizer__={...}" change).
This constraint ensures that the optimizer "works" and doesn't break (too much ;-)) the Python semantics, but it's more difficult to implement powerful optimizations.
I also found and fixed various kinds of bugs. In my code obviously, but also in the Python core, in various places. Some bugs only concern AST transformers which is a new feature, but I had to fix them. For example, Python didn't support negative line number delta in co_lntotab of code objects, and so line number were all wrong on optimized code. I merged my enhancement in the default branch of CPython (issue #26107).
In short, I focused on having something working (respecting the Python semantics), rather than spending time on writing optimizations.
--
When I asked explicitly "Is someone opposed to this PEP 509 [dict verion] ?", Barry Warsaw answered that a performance analysis is required. Extract of his mail:
"I still think this is maintenance and potential performance overhead we don't want to commit to long term unless it enables significant optimization. Since you probably can't prove that without some experimentation, this API should be provisional."
Last week, I ran some benchmarks and I have to admin that I was disappointed. Not only fatoptimizer doesn't make Python faster, but it makes it much slower on some tests!
http://fatoptimizer.readthedocs.org/en/latest/benchmarks.html
Quickly, I identified a major performance issue when nested functions are specialized, especially in Lib/json/encoder.py (tested by bm_json_v2.py benchmark). I fixed my optimizer to not specialize nested functions anymore. This simple change fixed the main performance issue. Reminder: in performance critical code, don't use nested functions! I will maybe propose patches for Lib/json/encoder.py to stop using nested functions.
I only ran benchmarks with the optimizer enabled. I now have to measure the overhead of my patches (PEP 509, 510 and 511) adding the API fat AST optimizers. The overhead must be negligible. For me, it's a requirement of the whole project. Changes must not make Python slower when the optimizer is not used.
fatoptimizer is faster on microbenchmarks, but I had to write manually some optimizations:
http://fatoptimizer.readthedocs.org/en/latest/microbenchmarks.html
IMHO fatoptimizer is not faster on macro benchmarks because it is not smart enough (yet) to generate the most interesting optimizations, like function inlining and specialization for argument types. You can estimate the speedup if you specialize manually your functions.
--
Barry also wrote: "Did you address my suggestion on python-ideas to make the new C API optionally compiled in?"
Well, it is an option, but I would prefer to have the API for AST optimizer directly built in Python.
The first beta version of Python 3.6 is scheduled in September 2016 (deadline for new features in Python 3.6), so I still have a few months to implement more powerful optimizations and prove that it can be faster ;-)
Victor _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/gmludo%40gmail.com
Hi,
2016-01-25 22:20 GMT+01:00 Ludovic Gasc
Just thanks for this big contribution. And maybe this project could give new ideas to optimize Python, who knows ?
Sorry for my long email. I should try to summarize next time :-) In short: FAT Python is not fast today, but it will be faster if you give me a few more months to implement optimizations which will unlock the real power of AST optimizers ;-) I have a looooong list of ideas of optimizations: https://fatoptimizer.readthedocs.org/en/latest/todo.html According to microbenchmarks, the most promising optimizations are functions inlining (Python function calls are slow :-/) and specialize the code for the type of arguments. And I agree to wait until fatoptimizer is proven to be faster than the regular CPython before taking a decision of my 3 PEPs (509, 510, 511). Victor
On Jan 25, 2016, at 13:43, Victor Stinner
According to microbenchmarks, the most promising optimizations are functions inlining (Python function calls are slow :-/) and specialize the code for the type of arguments.
Can you specialize a function with a C API function, or only with bytecode? I'm not sure how much benefit you'd get out of specializing list vs. generic iterable or int vs. whatever from an AST transform, but substituting raw C code, on the other hand...
On Mon, 25 Jan 2016 at 14:30 Andrew Barnert via Python-Dev < python-dev@python.org> wrote:
On Jan 25, 2016, at 13:43, Victor Stinner
wrote: According to microbenchmarks, the most promising optimizations are functions inlining (Python function calls are slow :-/) and specialize the code for the type of arguments.
Can you specialize a function with a C API function, or only with bytecode? I'm not sure how much benefit you'd get out of specializing list vs. generic iterable or int vs. whatever from an AST transform, but substituting raw C code, on the other hand...
Victor's work is only manipulation of ASTs and bytecode. If you want something that low-level you need to either reach for Cython or hope a project like Pyjion pays off.
Hi,
2016-01-25 23:28 GMT+01:00 Andrew Barnert
On Jan 25, 2016, at 13:43, Victor Stinner
wrote: According to microbenchmarks, the most promising optimizations are functions inlining (Python function calls are slow :-/) and specialize the code for the type of arguments.
Can you specialize a function with a C API function, or only with bytecode? I'm not sure how much benefit you'd get out of specializing list vs. generic iterable or int vs. whatever from an AST transform, but substituting raw C code, on the other hand...
As I wrote in the first part of my email, I redesigned to API to make it more generic. One of my change was to change PyFunction_Specialize() to not only accept code objects, but any callable object. The PEP 510 even contains an example using a builtin function as the specialized code: https://www.python.org/dev/peps/pep-0510/#using-builtin-function "On a microbenchmark, calling the C builtin takes 95 ns, whereas the original bytecode takes 155 ns (+60 ns): 1.6 times as fast. Calling directly chr(65) takes 76 ns." You can design an AST optimizer to compile some functions to C and then register them as specialized code at runtime. I have a side project to use Cython and/or pythran to specialize some functions using type annotation on parameters. Victor
On Jan 25, 2016, at 14:46, Victor Stinner
You can design an AST optimizer to compile some functions to C and then register them as specialized code at runtime. I have a side project to use Cython and/or pythran to specialize some functions using type annotation on parameters.
That last part is exactly what I was thinking of. One way in which cythonizing your code isn't 100% compatible is that if you, say, shadow or replace int or range, the cython code is now wrong. Which is exactly the kind of thing FAT can guard against. Which is very cool. Glad to see you already thought of that before me. :)
Hi Victor, I encourage you to proceed here. I would love to see your PEPs (509-511) incorporated into CPython. It's not that I consider Python slow (although some folks claim so), but performance improvements are always welcome; especially when I glance over diagrams like those: http://blog.carlesmateo.com/wp-content/uploads/2014/10/blog-carlesmateo-com-... So, I join Barry when he says, we want more benchmarking and definite results, however, I might be less strict than he is and say: - even if FAT might not optimize significantly (whatever definition we apply), PEP 509 to 511 are a great win for CPython - they provide a great infrastructure for optimizing CPython AND extending/experimenting Python as an ecosystem - FAT provides interesting insights into the field of optimizing a dynamic language So, keep up the good work. I am eager to see where this goes. If there's anything I can do, let me know. :) Best, Sven On 25.01.2016 19:16, Victor Stinner wrote:
Hi,
Summary: FAT Python is not faster, but it will be ;-)
--
When I started the FAT Python as a fork of CPython 3.6, I put everything in the same repository. Last weeks, I focused on splitting my giant patch (10k lines) into small reviewable patches. I wrote 3 PEP (509 dict version, 510 function specialziation, 511 code tranformers) and I enhanced the API to make it usable for more use cases than just FAT Python. I also created fatoptimizer (the AST optimizer) and fat (runtime dependency of the optimizer) projects on GitHub to separate clearly what should be outside Python core. For all links, see:
http://faster-cpython.readthedocs.org/fat_python.html
For the fatoptimizer project, my constraint is to be able to run the full Python test suite unmodified. In practice, I have to disable some optimizations by putting a "__fatoptimizer__= {...}" configuration to some test files. For example, I have to disable constant folding on test_bool because it tests that False+2 gives 2 at runtime, whereas the optimizer replaces directly False+2 with 2 during the compilation. Well, test_bool.py is not the best example because all tests pass with the constant folding optimization (if I comment my "__fatoptimizer__={...}" change).
This constraint ensures that the optimizer "works" and doesn't break (too much ;-)) the Python semantics, but it's more difficult to implement powerful optimizations.
I also found and fixed various kinds of bugs. In my code obviously, but also in the Python core, in various places. Some bugs only concern AST transformers which is a new feature, but I had to fix them. For example, Python didn't support negative line number delta in co_lntotab of code objects, and so line number were all wrong on optimized code. I merged my enhancement in the default branch of CPython (issue #26107).
In short, I focused on having something working (respecting the Python semantics), rather than spending time on writing optimizations.
--
When I asked explicitly "Is someone opposed to this PEP 509 [dict verion] ?", Barry Warsaw answered that a performance analysis is required. Extract of his mail:
"I still think this is maintenance and potential performance overhead we don't want to commit to long term unless it enables significant optimization. Since you probably can't prove that without some experimentation, this API should be provisional."
Last week, I ran some benchmarks and I have to admin that I was disappointed. Not only fatoptimizer doesn't make Python faster, but it makes it much slower on some tests!
http://fatoptimizer.readthedocs.org/en/latest/benchmarks.html
Quickly, I identified a major performance issue when nested functions are specialized, especially in Lib/json/encoder.py (tested by bm_json_v2.py benchmark). I fixed my optimizer to not specialize nested functions anymore. This simple change fixed the main performance issue. Reminder: in performance critical code, don't use nested functions! I will maybe propose patches for Lib/json/encoder.py to stop using nested functions.
I only ran benchmarks with the optimizer enabled. I now have to measure the overhead of my patches (PEP 509, 510 and 511) adding the API fat AST optimizers. The overhead must be negligible. For me, it's a requirement of the whole project. Changes must not make Python slower when the optimizer is not used.
fatoptimizer is faster on microbenchmarks, but I had to write manually some optimizations:
http://fatoptimizer.readthedocs.org/en/latest/microbenchmarks.html
IMHO fatoptimizer is not faster on macro benchmarks because it is not smart enough (yet) to generate the most interesting optimizations, like function inlining and specialization for argument types. You can estimate the speedup if you specialize manually your functions.
--
Barry also wrote: "Did you address my suggestion on python-ideas to make the new C API optionally compiled in?"
Well, it is an option, but I would prefer to have the API for AST optimizer directly built in Python.
The first beta version of Python 3.6 is scheduled in September 2016 (deadline for new features in Python 3.6), so I still have a few months to implement more powerful optimizations and prove that it can be faster ;-)
Victor _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/srkunze%40mail.de
2016-01-25 22:51 GMT+01:00 Sven R. Kunze
- they provide a great infrastructure for optimizing CPython AND extending/experimenting Python as an ecosystem
I hope that these API will create more optimizer projects than just fatoptimizer. For example, I expect more specialized optimizers like numba or pythran which are very efficient but more specific (ex: numeric computations) than fatoptimizer. Maybe not new optimizers, but just glue to existing static compilers (numba, pythran, cython, etc.).
If there's anything I can do, let me know. :)
Oh, they are a lot of things to do! My patches for PEP 509, 510 and 511 still need some love (reviews): http://bugs.python.org/issue26058 http://bugs.python.org/issue26098 http://bugs.python.org/issue26145 I'm finishing my patch adding ast.Constant. This one is less controversal, it has no impact on performance nor the Python semantics: http://bugs.python.org/issue26146 But these patches are boring C code. You may prefer to work on the funny fatoptimizer project which is written in pure Python: https://fatoptimizer.readthedocs.org/en/latest/ Victor
I'm very interested in it.
Ruby 2.2 and PHP 7 are faster than Python 2.
Python 3 is slower than Python 2.
Performance is a attractive feature. Python 3 lacks it.
How can I help your work?
On Tue, Jan 26, 2016 at 7:58 AM, Victor Stinner
2016-01-25 22:51 GMT+01:00 Sven R. Kunze
: - they provide a great infrastructure for optimizing CPython AND extending/experimenting Python as an ecosystem
I hope that these API will create more optimizer projects than just fatoptimizer.
For example, I expect more specialized optimizers like numba or pythran which are very efficient but more specific (ex: numeric computations) than fatoptimizer. Maybe not new optimizers, but just glue to existing static compilers (numba, pythran, cython, etc.).
If there's anything I can do, let me know. :)
Oh, they are a lot of things to do! My patches for PEP 509, 510 and 511 still need some love (reviews):
http://bugs.python.org/issue26058 http://bugs.python.org/issue26098 http://bugs.python.org/issue26145
I'm finishing my patch adding ast.Constant. This one is less controversal, it has no impact on performance nor the Python semantics:
http://bugs.python.org/issue26146
But these patches are boring C code. You may prefer to work on the funny fatoptimizer project which is written in pure Python:
https://fatoptimizer.readthedocs.org/en/latest/
Victor _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/songofacandy%40gmail.com
--
INADA Naoki
On Mon, 25 Jan 2016 at 18:22 INADA Naoki
I'm very interested in it.
Ruby 2.2 and PHP 7 are faster than Python 2. Python 3 is slower than Python 2. Performance is a attractive feature. Python 3 lacks it.
That is not a fair statement to make about Python 3. It entirely depends on your workload whether it is faster or slower. https://gist.github.com/brettcannon/9d19cc184ea45b3e7ca0 -Brett
How can I help your work?
On Tue, Jan 26, 2016 at 7:58 AM, Victor Stinner
wrote: 2016-01-25 22:51 GMT+01:00 Sven R. Kunze
: - they provide a great infrastructure for optimizing CPython AND extending/experimenting Python as an ecosystem
I hope that these API will create more optimizer projects than just fatoptimizer.
For example, I expect more specialized optimizers like numba or pythran which are very efficient but more specific (ex: numeric computations) than fatoptimizer. Maybe not new optimizers, but just glue to existing static compilers (numba, pythran, cython, etc.).
If there's anything I can do, let me know. :)
Oh, they are a lot of things to do! My patches for PEP 509, 510 and 511 still need some love (reviews):
http://bugs.python.org/issue26058 http://bugs.python.org/issue26098 http://bugs.python.org/issue26145
I'm finishing my patch adding ast.Constant. This one is less controversal, it has no impact on performance nor the Python semantics:
http://bugs.python.org/issue26146
But these patches are boring C code. You may prefer to work on the funny fatoptimizer project which is written in pure Python:
https://fatoptimizer.readthedocs.org/en/latest/
Victor _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
https://mail.python.org/mailman/options/python-dev/songofacandy%40gmail.com
-- INADA Naoki
_______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/brett%40python.org
On Jan 25, 2016, at 18:21, INADA Naoki
I'm very interested in it.
Ruby 2.2 and PHP 7 are faster than Python 2. Python 3 is slower than Python 2.
Says who? That was certainly true in the 3.2 days, but nowadays, most things that differ seem to be faster in 3.x. Maybe it's just the kinds of programs I write, but speedup in decoding UTF-8 that's usually ASCII (and then processing the decoded unicode when it's usually 1/4th the size), faster listcomps, and faster datetime seem to matter more than slower logging or slower imports. And that's just when running the same code; when you actually use new features, yield from is much faster than looping over yield; scandir blows away listdir; asyncio blows away asyncore or threading even harder; etc. Maybe if you do different things, you have a different experience. But if you have a specific problem, you'd do a lot better to file specific bugs for that problem than to just hope that everything magically gets so much faster that your bottleneck no longer matters.
Performance is a attractive feature. Python 3 lacks it.
When performance matters, people don't use Python 2, Ruby, or PHP, any more than they use Python 3. Or, rather, they use _any_ of those languages for the 95% of their code that doesn't matter, and C (often through existing libraries like NumPy--and try to find a good equivalent of that for Ruby or PHP) for the 5% that does.
On Tue, Jan 26, 2016 at 12:02 PM, Andrew Barnert
On Jan 25, 2016, at 18:21, INADA Naoki
wrote: I'm very interested in it.
Ruby 2.2 and PHP 7 are faster than Python 2. Python 3 is slower than Python 2.
Says who?
For example, http://benchmarksgame.alioth.debian.org/u64q/php.html In Japanese, many people compares language performance by microbench like fibbonacci.
That was certainly true in the 3.2 days, but nowadays, most things that differ seem to be faster in 3.x.
Python is little faster than ever in these years. But PHP and Ruby are much more faster than these years. Matz announced Ruby 3x3. Ruby hackers will make more effort to optimize ruby. http://engineering.appfolio.com/appfolio-engineering/2015/11/18/ruby-3x3
Maybe it's just the kinds of programs I write, but speedup in decoding UTF-8 that's usually ASCII (and then processing the decoded unicode when it's usually 1/4th the size), faster listcomps, and faster datetime seem to matter more than slower logging or slower imports. And that's just when running the same code; when you actually use new features, yield from is much faster than looping over yield; scandir blows away listdir; asyncio blows away asyncore or threading even harder; etc.
I know. But people compares language speed by simple microbench like fibbonacci. They doesn't use listcomp or libraries to compare *language* speed.
Maybe if you do different things, you have a different experience. But if you have a specific problem, you'd do a lot better to file specific bugs for that problem than to just hope that everything magically gets so much faster that your bottleneck no longer matters.
I did it sometimes. But I'd like to base language performance like function call more faster.
Performance is a attractive feature. Python 3 lacks it.
When performance matters, people don't use Python 2, Ruby, or PHP, any more than they use Python 3. Or, rather, they use _any_ of those languages for the 95% of their code that doesn't matter, and C (often through existing libraries like NumPy--and try to find a good equivalent of that for Ruby or PHP) for the 5% that does.
In the case of Web devs, many people choose main language from PHP, Ruby
and Python.
When peformance matters, they choose sub language from node.js, Go and
Scala.
While performance is not a matter when choosing first language, slowest of
three makes bad impression
and people feel less attractive about Python.
--
INADA Naoki
On January 25, 2016 9:32:07 PM CST, INADA Naoki
On Tue, Jan 26, 2016 at 12:02 PM, Andrew Barnert
wrote: On Jan 25, 2016, at 18:21, INADA Naoki
wrote: I'm very interested in it.
Ruby 2.2 and PHP 7 are faster than Python 2. Python 3 is slower than Python 2.
Says who?
For example, http://benchmarksgame.alioth.debian.org/u64q/php.html In Japanese, many people compares language performance by microbench like fibbonacci.
...does writing Fibonacci in a foreign language make a performance difference? Or did you mean "In Japan?"
That was certainly true in the 3.2 days, but nowadays, most things
that
differ seem to be faster in 3.x.
Python is little faster than ever in these years. But PHP and Ruby are much more faster than these years.
Matz announced Ruby 3x3. Ruby hackers will make more effort to optimize ruby. http://engineering.appfolio.com/appfolio-engineering/2015/11/18/ruby-3x3
Maybe it's just the kinds of programs I write, but speedup in decoding UTF-8 that's usually ASCII (and then processing the decoded unicode when it's usually 1/4th the size), faster listcomps, and faster datetime seem to matter more than slower logging or slower imports. And that's just when running the same code; when you actually use new features, yield from is much faster than looping over yield; scandir blows away listdir; asyncio blows away asyncore or threading even harder; etc.
I know. But people compares language speed by simple microbench like fibbonacci. They doesn't use listcomp or libraries to compare *language* speed.
Maybe if you do different things, you have a different experience. But if you have a specific problem, you'd do a lot better to file specific bugs for that problem than to just hope that everything magically gets so much faster that your bottleneck no longer matters.
I did it sometimes. But I'd like to base language performance like function call more faster.
Performance is a attractive feature. Python 3 lacks it.
When performance matters, people don't use Python 2, Ruby, or PHP,
more than they use Python 3. Or, rather, they use _any_ of those languages for the 95% of their code that doesn't matter, and C (often through existing libraries like NumPy--and try to find a good equivalent of
any that
for Ruby or PHP) for the 5% that does.
In the case of Web devs, many people choose main language from PHP, Ruby and Python. When peformance matters, they choose sub language from node.js, Go and Scala.
While performance is not a matter when choosing first language, slowest of three makes bad impression and people feel less attractive about Python.
-- Sent from my Nexus 5 with K-9 Mail. Please excuse my brevity.
On Tue, Jan 26, 2016 at 2:32 PM, INADA Naoki
I know. But people compares language speed by simple microbench like fibbonacci. They doesn't use listcomp or libraries to compare *language* speed.
Well, that's a stupid way to decide on a language. Here, look: Python
is faster than C. Proof!
rosuav@sikorsky:~$ time python3 fib.py
2880067194370816120
real 0m0.033s
user 0m0.032s
sys 0m0.000s
rosuav@sikorsky:~$ cat fib.py
import functools
@functools.lru_cache()
def fib(n):
if n < 2: return n
return fib(n-2) + fib(n-1)
print(fib(90))
rosuav@sikorsky:~$ gcc fib.c && time ./a.out
1134903170
real 0m9.104s
user 0m9.064s
sys 0m0.000s
rosuav@sikorsky:~$ cat fib.c
#include
Do you say I and many people are so fool?
People use same algorithm on every language when compares base language
performance [1].
[1] There are no solid definition about "Base language performance".
But it includes function call, method lookup, GC. It may include basic
string and arithmetic operations.
See here for example:
http://d.hatena.ne.jp/satosystems/20121228/1356655565
This article is written in 2012.
In this article, php 5.3 takes 85sec, Python 2.7 takes 53sec and CRuby 1.8
takes 213sec. (!!)
For now:
$ python2 -V
Python 2.7.11
$ time python2 -S fib.py
39088169
real 0m17.133s
user 0m16.970s
sys 0m0.055s
$ python3 -V
Python 3.5.1
$ time python3 -S fib.py
39088169
real 0m21.380s
user 0m21.337s
sys 0m0.028s
$ php -v
PHP 7.0.2 (cli) (built: Jan 7 2016 10:40:21) ( NTS )
Copyright (c) 1997-2015 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2015 Zend Technologies
$ time php fib.php
39088169
real 0m7.706s
user 0m7.654s
sys 0m0.027s
$ ruby -v
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin14]
$ time ruby fib.rb
39088169
real 0m6.195s
user 0m6.124s
sys 0m0.032s
Fibonacci microbench measures performance of function call.
When I said "Base language performance", I meant performance of
function call, attribute lookup, GC, etc...
PHP and Ruby made grate effort to improve base language performance.
While I'm fan of Python, I respect people made PHP and Ruby faster.
Of course, I respect people making Python faster too.
But I wonder if CPython is more faster, especially about global lookup and
function call.
--
INADA Naoki
On 1/26/2016 12:02 AM, INADA Naoki wrote:
People use same algorithm on every language when compares base language performance [1].
The python code is NOT using the same algorithm. The proof is that the Python function will return the correct value for, say fib(50) while most if not all the other versions will not. The domain of an algorithm is part of what characterizes an algorithm. -- Terry Jan Reedy
Terry Reedy writes:
On 1/26/2016 12:02 AM, INADA Naoki wrote:
People use same algorithm on every language when compares base language performance [1].
The python code is NOT using the same algorithm. The proof is that the Python function will return the correct value for, say fib(50) while most if not all the other versions will not.
True, but that's not a reasonable criterion for "same algorithm" in this context. Naoki's application ("base language performance" benchmarking) requires fib(n) only for n < 40, and run it in a loop 100 times if you want 2 more decimal places of precision ("40" is appropriate for an implementation with 32-bit ints). On that restricted domain the algorithm *is* the same. If you want to argue that the bigger domain is a better one to use for evaluating programming languages, be our guest. But then you're comparing apples (speed) to oranges (domain), and Naoki (or the Japanese benchmarkers) can argue that a smaller, more risky, domain is covered by "consenting adults" -- if you know there's a risk, you need to write code to deal with it, but if you know there isn't, you shouldn't have to accept lower performance. Obviously, I don't think that's an appropriate tradeoff myself, but that's based on "IMHO" not "comparison is invalid because algorithms differ".
On 1/26/2016 12:51 PM, Stephen J. Turnbull wrote:
Terry Reedy writes:
On 1/26/2016 12:02 AM, INADA Naoki wrote:
People use same algorithm on every language when compares base language performance [1].
The python code is NOT using the same algorithm. The proof is that the Python function will return the correct value for, say fib(50) while most if not all the other versions will not.
Let me try to be clearer. 1. Like everyone else, I would like Python function calls to be faster either in general or in special cases detected during compilation. This will require micro-benchmark for function calls that do just that. First time an empty loop, then time a loop with a call to an empty function. Do the same for various signatures, and maybe other special cases. 2. Cross-language micro-benchmarks aimed at timing specific operations are tough. To run on multiple languages, they must be restricted to a lowest-common-denominator of features. It is impossible to make every implementation perform exactly the same set of operations. Some languages may bundle features together. Some languages and implementations have optimizations that avoid unneeded operations. Not all optimizatons can be turned off. 3. While there are trends as to the speed of implementations of a language, benchmarks time particular implementations. Shedskin would compile fib to a C function that runs much faster than fib with the restricted subset of CPython allowed for the benchmark.
True, but that's not a reasonable criterion for "same algorithm" in this context. Naoki's application ("base language performance" benchmarking) requires fib(n) only for n < 40, and run it in a loop 100 times if you want 2 more decimal places of precision ("40" is appropriate for an implementation with 32-bit ints).
So you agree that the limit of 39 is not intrinsic to the fib function or its uses, but is an after-the-fact limit imposed to mask the bug proneness of using substitutes for integers. To my mind, a fairer and more useful benchmark of 'base language performance' based on fib would use a wider domain. The report would say that CPython (with lru_cache disallowed) is slow but works over a wide range of inputs, while some other implementations of other languages run faster for small inputs but fail catastrophically for larger inputs. Users could then make a more informed pick. Also see my answer to Sven Kunze. -- Terry Jan Reedy
Terry Reedy writes:
So you agree that the limit of 39 is not intrinsic to the fib function or its uses, but is an after-the-fact limit imposed to mask the bug proneness of using substitutes for integers.
I don't know what the limit used in the benchmark is, but it must be quite a bit lower than 50 for 32-bit integers and could be greater than 90 for 64-bit integers. And it's not "masking bugs", it's "respecting the domain of valid input", s'il vous plait.
To my mind, a fairer and more useful benchmark of 'base language performance' based on fib would use a wider domain.
"Fair", maybe. But why play this game at all? These benchmarks are simply not useful to users choosing languages, unless they already know the difficulties of interpreting benchmarks and are willing to expend the effort to account for them. Without that knowledge and effort, choosing a programming language based on microbenchmarks is like choosing a car based on the leg-length of the model sitting on the hood in the TV commercial.
The report would say that CPython (with lru_cache disallowed) is slow but works over a wide range of inputs,
No, the report would say "Use of this benchmark for cross-language comparison of function call speed is more or less inaccurate due to differences in representation of integers and in handling the possibility of exceptions in 'integer' arithmetic." You are picking one tiny difference, but there are potentially many, some quite a bit larger on the tested domain (for example, some languages may be able to optimize fib() to unboxed integers, in which case they'll blow away all those that don't).
Users could then make a more informed pick.
My point in my reply to Nick is that users aren't making informed picks. If they were, we wouldn't even be thinking about having this conversation. I'm not sure what they are doing (maybe, as Nick suggests, justifying their "tribal" prejudices?), but it's not that. ;-) Sure, other things being equal, better benchmarks will improve runtime performance, but other things are so far from being equal even an economist can't say "ceteris paribus" here. To expand that point: I don't really see a point in users (ie, developers in Python and other such languages) looking at these benchmarks except for the fun of feeling like implementers, to be honest. Even the implementers shouldn't much care about cross- language benchmarks, except that when a "similar"[1] language does significantly better on a particular benchmark, it's often useful to wonder "how dey do dat?!" Typically the answer is "they 'cheat'" == "fail one of the properties we consider required", but sometimes it's "ooh, that's cute, and I bet we could make Python work the same way" or "urkh, we can't do *that* (yuck!) but we could FATten up Python with similar effect". (Let me take this opportunity to say "Thank you, Victor!") Of course in the case of a controlled experiment like "configure in Victor's changes and run the benchmarks to make sure they're not detectably slower", they're invaluable regression tests, and more or less valuable (ie, YMMV) as measures of improvement to compare to costs they may impose in other features or (even more fuzzy) in developer time. Footnotes: [1] Whatever that means....
On January 25, 2016 9:59:36 PM CST, Chris Angelico
On Tue, Jan 26, 2016 at 2:32 PM, INADA Naoki
wrote: I know. But people compares language speed by simple microbench like
fibbonacci.
They doesn't use listcomp or libraries to compare *language* speed.
Well, that's a stupid way to decide on a language. Here, look: Python is faster than C. Proof!
rosuav@sikorsky:~$ time python3 fib.py 2880067194370816120
real 0m0.033s user 0m0.032s sys 0m0.000s rosuav@sikorsky:~$ cat fib.py import functools
@functools.lru_cache() def fib(n): if n < 2: return n return fib(n-2) + fib(n-1)
print(fib(90))
rosuav@sikorsky:~$ gcc fib.c && time ./a.out 1134903170
real 0m9.104s user 0m9.064s sys 0m0.000s rosuav@sikorsky:~$ cat fib.c #include
unsigned long fib(unsigned long n) { if (n < 2) return n; return fib(n-2) + fib(n-1); }
int main() { printf("%lu\n",fib(45)); }
*cough* -O3 *cough*
Algorithmic differences - even subtle ones - can easily outdo choice of language for run-time performance. And if you try to write a true C equivalent of that Python code, good luck - I'll have the Python one written and running while you're still trying to figure out how to write a cache, much less how to keep the syntax clean as you add a cache to an existing function.
Of course, rewriting the whole thing to work iteratively instead of double-recursively will make a dramatic difference to both programs. That's an unsubtle algorithmic difference, and if you're coding like that, you probably can't see the difference in performance between any two languages at anything up to a machine word (about the 90th or so Fibonacci number, on a 64-bit system) - all you'll see is the startup performance. As soon as you go beyond a machine word, Python massively trumps C, because its default integer type is a bignum. Going beyond a machine word in C is a hassle. Going beyond a machine word in Python 2 is almost insignificant - hey look, now your repr has an 'L' on the end, and performance is immeasurably worse. In Python 3, there's no machine word whatsoever.
So, yeah... Python beats C for Fibonacci calculation, too. You just have to not be stupid with your benchmarking.
ChrisA _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/rymg19%40gmail.com
-- Sent from my Nexus 5 with K-9 Mail. Please excuse my brevity.
On Wed, Jan 27, 2016 at 2:28 AM, Ryan Gonzalez
rosuav@sikorsky:~$ gcc fib.c && time ./a.out 1134903170
real 0m9.104s user 0m9.064s sys 0m0.000s rosuav@sikorsky:~$ cat fib.c #include
unsigned long fib(unsigned long n) { if (n < 2) return n; return fib(n-2) + fib(n-1); }
int main() { printf("%lu\n",fib(45)); }
*cough* -O3 *cough*
Oh, I'm sorry. Let's try it again. rosuav@sikorsky:~$ gcc -O3 fib.c && time ./a.out 1134903170 real 0m3.153s user 0m3.088s sys 0m0.052s Cool! Seems to be linear. From which we can deduce that Python on my system was compiled at about -O275. ChrisA
On Jan 25, 2016, at 19:32, INADA Naoki
On Tue, Jan 26, 2016 at 12:02 PM, Andrew Barnert
wrote: On Jan 25, 2016, at 18:21, INADA Naoki wrote: I'm very interested in it.
Ruby 2.2 and PHP 7 are faster than Python 2. Python 3 is slower than Python 2.
Says who?
For example, http://benchmarksgame.alioth.debian.org/u64q/php.html In Japanese, many people compares language performance by microbench like fibbonacci.
"In Japan, the hand is sharper than a knife [man splits board with karate chop], but the same doesn't work with a tomato [man splatters tomato all over himself with karate chop]." A cheap knife really is better than a karate master at chopping tomatoes. And Python 2 really is better than Python 3 at doing integer arithmetic on the edge of what can fit into a machine word. But so what? Without seeing any of your Japanese web code, much less running a profiler, I'm willing to bet that your code is rarely CPU-bound, and, when it is, it spends a lot more time doing things like processing Unicode strings that are almost always UCS-2 (about 110% slower on Python 2) than doing this kind of arithmetic (9% faster on Python 2), or cutting tomatoes (TypeError on both versions).
On Tue, Jan 26, 2016 at 2:44 PM, Andrew Barnert
On Jan 25, 2016, at 19:32, INADA Naoki
wrote: On Tue, Jan 26, 2016 at 12:02 PM, Andrew Barnert
wrote: On Jan 25, 2016, at 18:21, INADA Naoki
wrote: I'm very interested in it.
Ruby 2.2 and PHP 7 are faster than Python 2. Python 3 is slower than Python 2.
Says who?
For example, http://benchmarksgame.alioth.debian.org/u64q/php.html In Japanese, many people compares language performance by microbench like fibbonacci.
"In Japan, the hand is sharper than a knife [man splits board with karate chop], but the same doesn't work with a tomato [man splatters tomato all over himself with karate chop]."
A cheap knife really is better than a karate master at chopping tomatoes. And Python 2 really is better than Python 3 at doing integer arithmetic on the edge of what can fit into a machine word. But so what? Without seeing any of your Japanese web code, much less running a profiler, I'm willing to bet that your code is rarely CPU-bound, and, when it is, it spends a lot more time doing things like processing Unicode strings that are almost always UCS-2 (about 110% slower on Python 2) than doing this kind of arithmetic (9% faster on Python 2), or cutting tomatoes (TypeError on both versions).
Calm down, please.
I didn't say "microbench is more important than macrobench".
While editor is not a main problem of software development, people likes
comparing vim and emacs.
Like that, Japanese dev people likes comparing speed.
While it's not a real problem of typical application, new people should
choose first (and probably main)
editor and language.
Slowest on such a basic microbench gives bad impression for them.
Additionally, some application (e.g. traversing DOM) makes much function
calls.
Faster function call may makes some *real* application faster.
--
INADA Naoki
INADA Naoki writes:
For example, http://benchmarksgame.alioth.debian.org/u64q/php.html In Japanese, many people compares language performance by microbench like fibbonacci.
True enough. But as a teacher in a Japanese engineering school, I am ashamed to see that posted to a public list. We Japanese ;-) need to get over that tendency (and not just in programming, my own biggest battle is against those who worship goodness-of-fit statistics). Our universities are doing an awful job at getting "big picture thinking" across to our students. I see that you respond that you're talking about "base language performance" which is a big improvement over blind faith in micro- benchmarks, but still it's a matter of pulling your nose back from the bark so you can see the tree. At least from the point of view of the computations the people around me are doing with these languages, you still miss the forest.
While performance is not a matter when choosing first language, slowest of three makes bad impression and people feel less attractive about Python.
My school is the one that Matz graduated from (different department), and as far as I can see (which is pretty local, I admit), Python is a clear first and growing as a teaching language and as a glue language for research computations. Java is second for both[1], Ruby is rare, and PHP just isn't on the map. I see some lab home pages using Ruby-on-Rails, and a couple of Mediawiki installations and the like based on PHP. For me personally, PHP and Ruby are both unusable for *performance* reasons: I need something like Pandas, which is based on NumPy, and at least the last time I checked a couple years ago Ruby had no equivalent to NumPy, let alone Pandas. (For PHP I asked the nearest PHP fanboy web programmer, so I could be way wrong about no efficient computation for PHP.) At least as used at this university, I just don't see a performance issue that Python needs to be specifically worried about. That said, optimization is important, and IMO anything that allows 1% of people currently writing (and debugging ...) modules in C for performance reasons to write them in pure Python instead is a win. But to me, relieving programmer pain, not microbenchmarks, should be the performance measure we care about (even if others do care about those benchmarks). Measure them, yes, but focus on them only when we're pretty sure that poor benchmark numbers are associated with programmer pain. Footnotes: [1] Java was clearly first as a teaching language until 2010 or so, and since most of our grad students and assistant profs were students here in that era, I suspect its persistence is just the inertia that goes with academic nepotism.
On 26 January 2016 at 17:16, Stephen J. Turnbull
Our universities are doing an awful job at getting "big picture thinking" across to our students.
That problem isn't specific to Japan - I'm not aware of *anywhere* that does a particularly good job of teaching developers not to get tribal about their programming language choice, and instead evaluate their options based on their specific problem, the team that will be working on it, and the pre-existing problem solving tools available in that ecosystem. As a result, folks making programming language choices based on criteria that aren't actually relevant to the problem they're trying to solve is going to be a fact of life. While improving those kinds of metrics isn't a *reason* to do anything, it does count as an added bonus when it comes as a beneficial side effect of working on something else (such as the function specialisation infrastructure underpinning Victor's optimiser project). Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
Nick Coghlan writes:
On 26 January 2016 at 17:16, Stephen J. Turnbull
wrote:
Our universities are doing an awful job at getting "big picture thinking" across to our students.
That problem isn't specific to Japan - I'm not aware of *anywhere* that does a particularly good job of teaching developers not to get tribal about their programming language choice,
But that's a different issue. The approach that Naoki describes isn't "tribal", in fact it's the exact opposite: it's an attempt to base such decisions on strictly objective measures.
and instead evaluate their options based on their specific problem, the team that will be working on it, and the pre-existing problem solving tools available in that ecosystem.
One of which is the language itself, and the team's experience with it. "We're a C++/Java/Python/Ruby/Brainf!ck/assembler/COBOL shop" isn't a bad heuristic in most cases -- outside of research and/or "we also walk dogs" generalist consultancies -- especially when you're under pressure from the bean-counting department to reduce costs. That heuristic is hard to distinguish from "tribalism", though. AFAICT, in fact, the generalists (including massive entities like IBM and Google, as well as companies like Red Hat and cooperatives like Debian) are quite good at the kind of evaluation you describe. And Python has been quite good at targeting the kinds of improvements that make it appealing to people who can and do do that kind of evaluation, in more and more areas.
While improving those kinds of metrics isn't a *reason* to do anything, it does count as an added bonus when it comes as a beneficial side effect of working on something else (such as the function specialisation infrastructure underpinning Victor's optimiser project).
Sure, but that's a "have your cake and eat it too" situation. Nobody's going to complain about that! If Naoki -- or anybody else -- wants to work on optimizations enabled by FAT Python, more power to them, I say. I just would like to see them reviewed with the goal of making Python a better language for solving a wide variety of problems, rather than strictly focusing on benchmarks. If the benchmarks can be improved without closing off potential syntax improvements or restricting the domain of algorithms (cf Terry's comment), wonderful! I thought Chris's point about efficient algorithms that would be hard to implement correctly in other languages but are easy to do in Python *because* of Python's carefully crafted, but not always maximally speedy, semantics was especially apropos here. Of course his claim that Python is faster than C is tongue in cheek, and a caching version of fibonacci wouldn't be that hard to write in C, and an iterative version even easier. But others have pointed out many other syntaxes (comprehensions, generators, yield from, and so on) that put together often make efficient computation TOOWTDI. That, to me, is The Python Advantage.
I completely agree with INADA. It's like saying, because a specific crossroad features a higher accident rate, *people need to change their driving behavior*. *No!* People won't change and it's not necessary either. The crossroad needs to be changed to be safer. Same goes for Python. If it's slow using the very same piece of code (even superficially), you better make the language faster. Developers won't change and they won't change their code either. Just not necessary. Btw. it would be a great feature for Python 3 to be faster than Python 2. I've heard a lot of complaints of the scientific community that Python is slow. Would Python 3 be significantly faster than Python 2, that'll be a huge reason to upgrade (and would create pressure to upgrade libs as well). They are satisfied with Python so far, but would there be a language equally readable/maintainable and 10x faster (of course proven by some weird micro benchmarks - incomprehensible to most nervous subscribers to this list), they would readily switch over. I for one hope that *Python itself will be that language* in the foreseeable future. This is some sort of marketing but also requires hard facts indeed. Best, Sven
On 1/26/2016 12:35 PM, Sven R. Kunze wrote:
I completely agree with INADA.
I an not sure you do.
It's like saying, because a specific crossroad features a higher accident rate, *people need to change their driving behavior*. *No!* People won't change and it's not necessary either. The crossroad needs to be changed to be safer.
Safer crossroads tend to be slower unless one switched to alternate designs that eliminate crossing streams of traffic. Python is safer, in everyday use as well as in artificial benchmarks, and is slower as a result. Languages that don't have integers but use residue classes (with wraparound) or finite integer classes (with overflow) as a (faster) substitute have, in practice, lots of accidents (bugs) when used by non-experts. Guido noticed this, gave up on changing coder behavior, and put the expert behavior of checking for wraparound/overflow and switching to real integers (longs) into the language. (I forget when this was added.) The purpose of the artificially low input to fib() is to hide and avoid the bugginess of most languages. The analogous trick with testing crossroads would be to artificially restrict the density of cars to mask the accident-proneness of a 'fast, consenting-adults' crossroads with no stop signs and no stop lights.
Same goes for Python. If it's slow using the very same piece of code (even superficially), you better make the language faster. Developers won't change and they won't change their code either. Just not necessary.
Instead of making people rewrite fib to dramatically increase speed, we added the lru-cache decorator to get most of the benefit without a rewrite. But Inada rejected this Python speedup. An ast optimizer could potentially do the same speedup without the explicit decorator. (No side-effects? Multiple recursive calls? Add a cache!)
Btw. it would be a great feature for Python 3 to be faster than Python 2.
We all agree on that. One way for this to happen is to add optimizers that would make Python 'cheat' on micrebenchmarks -- Terry Jan Reedy
On 27.01.2016 11:59, Terry Reedy wrote:
On 1/26/2016 12:35 PM, Sven R. Kunze wrote:
I completely agree with INADA.
I an not sure you do.
I am sure I am. He wants to solve a problem the way that is natural to him as a unique human being.
It's like saying, because a specific crossroad features a higher accident rate, *people need to change their driving behavior*. *No!* People won't change and it's not necessary either. The crossroad needs to be changed to be safer.
Safer crossroads tend to be slower unless one switched to alternate designs that eliminate crossing streams of traffic.
So Python can be safer AND faster ( = different design) if we try hard enough.
Languages that don't have integers but use residue classes (with wraparound) or finite integer classes (with overflow) as a (faster) substitute have, in practice, lots of accidents (bugs) when used by non-experts. Guido noticed this, gave up on changing coder behavior, and put the expert behavior of checking for wraparound/overflow and switching to real integers (longs) into the language. (I forget when this was added.)
I am glad he did because it helps humans solve their problems in a natural way without artificial boundaries. :)
The purpose of the artificially low input to fib() is to hide and avoid the bugginess of most languages. The analogous trick with testing crossroads would be to artificially restrict the density of cars to mask the accident-proneness of a 'fast, consenting-adults' crossroads with no stop signs and no stop lights.
I am completely with you here, however I disagree about suspected hiding/avoiding mentality. You say: Python -> *no problem with big integers but slow at small integers* Other Language -> *faster but breaks at big integers* Yes. That's it. We haven't solved the human side, however. A human AGAIN would need to compromise on either speed or safety. My point is: it would be insanely great if Python could be more like "*fast AND no problem with big integers*". No compromise here (at least no noticeable). So, people could entirely *concentrate on their problem domain* without every worrying about such tiny little, nitty-gritty computer science details. I love computer science but people of other domains don't have the time nor the knowledge to decide properly. That's the reason why they might decide by using some weird micro-benchmarks. Just humans.
Same goes for Python. If it's slow using the very same piece of code (even superficially), you better make the language faster. Developers won't change and they won't change their code either. Just not necessary.
Instead of making people rewrite fib to dramatically increase speed, we added the lru-cache decorator to get most of the benefit without a rewrite. But Inada rejected this Python speedup. An ast optimizer could potentially do the same speedup without the explicit decorator. (No side-effects? Multiple recursive calls? Add a cache!)
Bingo! That's the spirit. Why that decorator in the first place? Hey, I mean, if I ever want to write some cryptic-looking source code with 3-letters abbreviations (LRU), I use Assembler again. But I discovered and love Python and I never want to go back when my problem domain does not require me to. So, when a machine can detect such an optimization, hell, do it, please. It's more likely that I apply it at the wrong function AND only in 10% of the correct cases: missing 90% and introducing some wild errors. Again human stuff.
Btw. it would be a great feature for Python 3 to be faster than Python 2.
We all agree on that. One way for this to happen is to add optimizers that would make Python 'cheat' on micrebenchmarks
Then, we are all set. :) Best, Sven
On Wed, 27 Jan 2016 at 10:12 Sven R. Kunze
On 27.01.2016 11:59, Terry Reedy wrote:
On 1/26/2016 12:35 PM, Sven R. Kunze wrote:
I completely agree with INADA.
I an not sure you do.
I am sure I am. He wants to solve a problem the way that is natural to him as a unique human being.
It's like saying, because a specific crossroad features a higher accident rate, *people need to change their driving behavior*. *No!* People won't change and it's not necessary either. The crossroad needs to be changed to be safer.
Safer crossroads tend to be slower unless one switched to alternate designs that eliminate crossing streams of traffic.
So Python can be safer AND faster ( = different design) if we try hard enough.
Languages that don't have integers but use residue classes (with wraparound) or finite integer classes (with overflow) as a (faster) substitute have, in practice, lots of accidents (bugs) when used by non-experts. Guido noticed this, gave up on changing coder behavior, and put the expert behavior of checking for wraparound/overflow and switching to real integers (longs) into the language. (I forget when this was added.)
I am glad he did because it helps humans solve their problems in a natural way without artificial boundaries. :)
The purpose of the artificially low input to fib() is to hide and avoid the bugginess of most languages. The analogous trick with testing crossroads would be to artificially restrict the density of cars to mask the accident-proneness of a 'fast, consenting-adults' crossroads with no stop signs and no stop lights.
I am completely with you here, however I disagree about suspected hiding/avoiding mentality. You say:
Python -> *no problem with big integers but slow at small integers* Other Language -> *faster but breaks at big integers*
Yes. That's it.
We haven't solved the human side, however. A human AGAIN would need to compromise on either speed or safety.
My point is: it would be insanely great if Python could be more like "*fast AND no problem with big integers*". No compromise here (at least no noticeable).
And this is why this entire email thread has devolved into a conversation that isn't really going anywhere. This whole thread has completely lost track of the point of Victor's earlier email saying "I'm still working on my FAT work and don't take any notice of the performance numbers until more stuff gets finished". And this discussion of what benchmarks to care about is rather pointless since the core team has an implicit understanding that any performance improvement is taken into consideration in terms of balancing complexity in CPython with how much improvement it gets us. So if someone wants to speed up Fibonacci then they are welcome to try, but the solution must be maintainable in proportion to the speed increase it buys Python as a whole. -Brett
So, people could entirely *concentrate on their problem domain* without every worrying about such tiny little, nitty-gritty computer science details. I love computer science but people of other domains don't have the time nor the knowledge to decide properly. That's the reason why they might decide by using some weird micro-benchmarks. Just humans.
Same goes for Python. If it's slow using the very same piece of code (even superficially), you better make the language faster. Developers won't change and they won't change their code either. Just not necessary.
Instead of making people rewrite fib to dramatically increase speed, we added the lru-cache decorator to get most of the benefit without a rewrite. But Inada rejected this Python speedup. An ast optimizer could potentially do the same speedup without the explicit decorator. (No side-effects? Multiple recursive calls? Add a cache!)
Bingo! That's the spirit.
Why that decorator in the first place? Hey, I mean, if I ever want to write some cryptic-looking source code with 3-letters abbreviations (LRU), I use Assembler again. But I discovered and love Python and I never want to go back when my problem domain does not require me to. So, when a machine can detect such an optimization, hell, do it, please. It's more likely that I apply it at the wrong function AND only in 10% of the correct cases: missing 90% and introducing some wild errors.
Again human stuff.
Btw. it would be a great feature for Python 3 to be faster than Python 2.
We all agree on that. One way for this to happen is to add optimizers that would make Python 'cheat' on micrebenchmarks
Then, we are all set. :)
Best, Sven _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/brett%40python.org
On 27.01.2016 19:33, Brett Cannon wrote:
And this is why this entire email thread has devolved into a conversation that isn't really going anywhere. This whole thread has completely lost track of the point of Victor's earlier email saying "I'm still working on my FAT work and don't take any notice of the performance numbers until more stuff gets finished". And this discussion of what benchmarks to care about is rather pointless since the core team has an implicit understanding that any performance improvement is taken into consideration in terms of balancing complexity in CPython with how much improvement it gets us. So if someone wants to speed up Fibonacci then they are welcome to try, but the solution must be maintainable in proportion to the speed increase it buys Python as a whole.
+1
On 27 January 2016 at 03:35, Sven R. Kunze
I completely agree with INADA.
It's like saying, because a specific crossroad features a higher accident rate, people need to change their driving behavior. No! People won't change and it's not necessary either. The crossroad needs to be changed to be safer.
Umm, no, that's not how this works - developers contribute to community driven projects for their *own* reasons. Nobody gets to tell them what to do unless they're paying them. Micro-optimising a poor algorithm won't deliver macro level improvements because macro level code uses things like space-speed trade-offs to improve the algorithmic efficiency (as in the example of applying functools.lru_cache to a naive recursive fibonacci implementation). Victor's work on FAT optimiser is interesting because it offers opportunities to speed up even code that is already algorithmically efficient, as well as making CPython a better platform for experimenting with those kinds of changes. More generally though, much larger opportunities for improvement lie in persuading people to *stop writing code*, and instead spending more of their time on finding and assembling code other people have *already written* into solutions to interesting problems. *That's* the kind of improvement that turns enormously complex problems like facial recognition into 25 line Python scripts: https://realpython.com/blog/python/face-recognition-with-python/ Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
On 27.01.2016 12:16, Nick Coghlan wrote:
On 27 January 2016 at 03:35, Sven R. Kunze
wrote: I completely agree with INADA.
It's like saying, because a specific crossroad features a higher accident rate, people need to change their driving behavior. No! People won't change and it's not necessary either. The crossroad needs to be changed to be safer. Umm, no, that's not how this works
That's exactly how it works, Nick. INADA uses Python as I use crossroads each day. Daily human business. If you read his post carefully, you can discover that he just presented to you his perspective of the world. Moreover, I can assure you that he's not alone. As usual with humans it's not about facts or mathematically proven theorems but *perception*. It's more about marketing, little important details (or unimportant ones depending on whom you ask) and so on. Stating that he has a wrong perspective will not change anything. Believing that Python is treated unfair will not change that either. Most people believe what they see. When they see a "FUNCTION CALL", it's the same in every language. Why? Because it looks like a function call ( name + parentheses ), it's called "function call" even if it's implemented completely differently. It even doesn't matter if we use commas, 'def', return types, etc. Because people understand the bigger concept, so that is what people want to compare. Average Joe doesn't care and does not understand. He looks at the benchmarks. That is something he can understand. "While performance is not a matter when choosing first language, slowest of three makes bad impression and people feel less attractive about Python." << just like that Not saying that INADA is an Average Joe, but I think you get the idea.
- developers contribute to community driven projects for their *own* reasons. Nobody gets to tell them what to do unless they're paying them.
Bit off-topic.
Micro-optimising a poor algorithm won't deliver macro level improvements because macro level code uses things like space-speed trade-offs to improve the algorithmic efficiency (as in the example of applying functools.lru_cache to a naive recursive fibonacci implementation).
I completely agree, Nick. :) But that isn't the issue here.
Victor's work on FAT optimiser is interesting because it offers opportunities to speed up even code that is already algorithmically efficient, as well as making CPython a better platform for experimenting with those kinds of changes.
Exactly. :)
More generally though, much larger opportunities for improvement lie in persuading people to *stop writing code*, and instead spending more of their time on finding and assembling code other people have *already written* into solutions to interesting problems. *That's* the kind of improvement that turns enormously complex problems like facial recognition into 25 line Python scripts: https://realpython.com/blog/python/face-recognition-with-python/
Interesting post. :) Thanks. Btw. I completely agree with you on the "improve programming education", but not everybody can do it; and not everybody wants to learn and to practice it properly. Best, Sven
On 28 January 2016 at 04:40, Sven R. Kunze
On 27.01.2016 12:16, Nick Coghlan wrote:
Umm, no, that's not how this works That's exactly how it works, Nick.
INADA uses Python as I use crossroads each day. Daily human business.
If you read his post carefully, you can discover that he just presented to you his perspective of the world. Moreover, I can assure you that he's not alone. As usual with humans it's not about facts or mathematically proven theorems but perception. It's more about marketing, little important details (or unimportant ones depending on whom you ask) and so on. Stating that he has a wrong perspective will not change anything.
The only part I disagree with is requesting that *other people* care about marketing numbers if that's not something they're already inclined to care about. I'm not in any way disputing that folks make decisions based on inappropriate metrics, nor that it bothers some folks that there are dozens of perfectly viable programming languages people may choose to use instead of Python. The fact remains that contributors to open source projects work on what they want to work on or on what their employers pay them to work on (for a lucky few, those are the same thing), so telling other contributors that they're working on the "wrong thing" because their priorities differ from our priorities is almost always going to be irritating rather than helpful. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
Please stop.
I'm sorry about messing up this thread.
I just wanted to represent why I'm very interested in Victor's efforts.
Regards.
On Thu, Jan 28, 2016 at 4:58 PM, Nick Coghlan
On 27.01.2016 12:16, Nick Coghlan wrote:
Umm, no, that's not how this works That's exactly how it works, Nick.
INADA uses Python as I use crossroads each day. Daily human business.
If you read his post carefully, you can discover that he just presented to you his perspective of the world. Moreover, I can assure you that he's not alone. As usual with humans it's not about facts or mathematically proven theorems but perception. It's more about marketing, little important
On 28 January 2016 at 04:40, Sven R. Kunze
wrote: details (or unimportant ones depending on whom you ask) and so on. Stating that he has a wrong perspective will not change anything.
The only part I disagree with is requesting that *other people* care about marketing numbers if that's not something they're already inclined to care about. I'm not in any way disputing that folks make decisions based on inappropriate metrics, nor that it bothers some folks that there are dozens of perfectly viable programming languages people may choose to use instead of Python.
The fact remains that contributors to open source projects work on what they want to work on or on what their employers pay them to work on (for a lucky few, those are the same thing), so telling other contributors that they're working on the "wrong thing" because their priorities differ from our priorities is almost always going to be irritating rather than helpful.
Cheers, Nick.
-- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
--
INADA Naoki
On 28 January 2016 at 18:30, INADA Naoki
Please stop.
I'm sorry about messing up this thread.
Not your fault at all! This is just a particular bugbear of mine, since software architecture design (including appropriate programming language selection) is an even more poorly understood discipline than software development in general :)
I just wanted to represent why I'm very interested in Victor's efforts.
And thanks for posting that, as it is indeed cool that the optimisation efforts currently being discussed may result in performance improvements on some of the simplified micro-benchmarks popular in programming language shootouts. There's no way you could have anticipated the subsequent tangential discussion on motives for contributing to open source projects, and the impact that has on what we can reasonably expect from fellow contributors. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
About benchmarks ... I've been there and it's not benchmarks that decide
whether something succeeds or fails.
(I found this old discussion
https://groups.google.com/forum/#!topic/comp.lang.lisp/pF_wjA_A9fc which
mentions FIB (also TAK https://en.wikipedia.org/wiki/Tak_(function),
which is rather more brutal) ... do you recognize the language that got an
implementation that was competitive with C in performance, was vastly more
expressive, yet failed to catch on?)
OTOH, good performance is never a bad thing and sometimes is a necessity;
so I applau this work.
On 28 January 2016 at 01:39, Nick Coghlan
On 28 January 2016 at 18:30, INADA Naoki
wrote: Please stop.
I'm sorry about messing up this thread.
Not your fault at all! This is just a particular bugbear of mine, since software architecture design (including appropriate programming language selection) is an even more poorly understood discipline than software development in general :)
I just wanted to represent why I'm very interested in Victor's efforts.
And thanks for posting that, as it is indeed cool that the optimisation efforts currently being discussed may result in performance improvements on some of the simplified micro-benchmarks popular in programming language shootouts.
There's no way you could have anticipated the subsequent tangential discussion on motives for contributing to open source projects, and the impact that has on what we can reasonably expect from fellow contributors.
Cheers, Nick.
-- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/pludemann%40google.com
Hi,
2016-01-26 3:21 GMT+01:00 INADA Naoki
How can I help your work?
I don't know exactly yet, but I started to write a documentation to explain how to contribute: http://faster-cpython.readthedocs.org/fat_python.html#how-can-you-contribute You may contact me directly ;-) Victor
Hi, will look into it soon. :) Best, Sven On 26.01.2016 16:32, Victor Stinner wrote:
Hi,
2016-01-26 3:21 GMT+01:00 INADA Naoki
: How can I help your work? I don't know exactly yet, but I started to write a documentation to explain how to contribute: http://faster-cpython.readthedocs.org/fat_python.html#how-can-you-contribute
You may contact me directly ;-)
Victor
On Mon, Jan 25, 2016 at 11:58:12PM +0100, Victor Stinner wrote:
... Oh, they are a lot of things to do! ...
Just wondering, do you also need a set of (abusive) test-cases which check 100% conformity to the CPython semantics? I'm sure many of us would be able to whip up some ideas of things that are possible with Python and are of the kind "but you should not do that! That's bad programming!" which may or may not break the optimizations (especially specialized functions). I'm thinking of things like def override_length_function_test(): global len value = len("abc") len = lambda obj: ord(obj[0])) value += len("abc") assert value == 3 + 97, "Outdated `len` used." And also cases where `len` was changed not in the function itself, but in another function that was called indirectly (maybe 4 functions down, one of which was monkey-patched in after the compilation step): module_a.py def test_func(callback): value = len("abc") callback() value += len("abc") assert value == 3 + 97, "Outdated `len` used." module_b.py import module_a def override_length_function_test(): def callback(): module_a.len = lambda obj: ord(obj[0]) assert module_a.test_func(callback) == 3 + 97, "Outdated `len` used." (I'm sure some of the other readers of this list can be even more creative in trying to show that making optimizations like this can break semantics.) Other fun tricks I'd like to try is overriding the `len` method from a signal handler, what happens when you monkey-patch a dependent method, having `__getitem__` and `__getattr__` on some value override `len`. Basically: trying things that I normally should not try during my working hours, on account of wanting to still have a job the next day. Kind regards, Sjoerd Job
On 27 January 2016 at 05:23, Sjoerd Job Postmus
On Mon, Jan 25, 2016 at 11:58:12PM +0100, Victor Stinner wrote:
... Oh, they are a lot of things to do! ...
Just wondering, do you also need a set of (abusive) test-cases which check 100% conformity to the CPython semantics? I'm sure many of us would be able to whip up some ideas of things that are possible with Python and are of the kind "but you should not do that! That's bad programming!" which may or may not break the optimizations (especially specialized functions).
I'm thinking of things like
def override_length_function_test(): global len value = len("abc") len = lambda obj: ord(obj[0])) value += len("abc") assert value == 3 + 97, "Outdated `len` used."
And also cases where `len` was changed not in the function itself, but in another function that was called indirectly (maybe 4 functions down, one of which was monkey-patched in after the compilation step):
module_a.py def test_func(callback): value = len("abc") callback() value += len("abc") assert value == 3 + 97, "Outdated `len` used."
module_b.py import module_a def override_length_function_test(): def callback(): module_a.len = lambda obj: ord(obj[0]) assert module_a.test_func(callback) == 3 + 97, "Outdated `len` used."
(I'm sure some of the other readers of this list can be even more creative in trying to show that making optimizations like this can break semantics.)
Other fun tricks I'd like to try is overriding the `len` method from a signal handler, what happens when you monkey-patch a dependent method, having `__getitem__` and `__getattr__` on some value override `len`.
Basically: trying things that I normally should not try during my working hours, on account of wanting to still have a job the next day.
Kind regards, Sjoerd Job
Maybe I'm just nasty, but IMO those kinds of "torture tests" are just as valuable in general, so I'd encourage people to submit patches to the main Python test suite to add them. Paul
Python has test_dynamic which tests such corner cases. For example, test_modify_builtins_while_generator_active(): "Modify the builtins out from under a live generator." https://hg.python.org/cpython/file/58266f5101cc/Lib/test/test_dynamic.py#l49 Victor 2016-01-27 10:28 GMT+01:00 Paul Moore
On 27 January 2016 at 05:23, Sjoerd Job Postmus
wrote: On Mon, Jan 25, 2016 at 11:58:12PM +0100, Victor Stinner wrote:
... Oh, they are a lot of things to do! ...
Just wondering, do you also need a set of (abusive) test-cases which check 100% conformity to the CPython semantics? I'm sure many of us would be able to whip up some ideas of things that are possible with Python and are of the kind "but you should not do that! That's bad programming!" which may or may not break the optimizations (especially specialized functions).
I'm thinking of things like
def override_length_function_test(): global len value = len("abc") len = lambda obj: ord(obj[0])) value += len("abc") assert value == 3 + 97, "Outdated `len` used."
And also cases where `len` was changed not in the function itself, but in another function that was called indirectly (maybe 4 functions down, one of which was monkey-patched in after the compilation step):
module_a.py def test_func(callback): value = len("abc") callback() value += len("abc") assert value == 3 + 97, "Outdated `len` used."
module_b.py import module_a def override_length_function_test(): def callback(): module_a.len = lambda obj: ord(obj[0]) assert module_a.test_func(callback) == 3 + 97, "Outdated `len` used."
(I'm sure some of the other readers of this list can be even more creative in trying to show that making optimizations like this can break semantics.)
Other fun tricks I'd like to try is overriding the `len` method from a signal handler, what happens when you monkey-patch a dependent method, having `__getitem__` and `__getattr__` on some value override `len`.
Basically: trying things that I normally should not try during my working hours, on account of wanting to still have a job the next day.
Kind regards, Sjoerd Job
Maybe I'm just nasty, but IMO those kinds of "torture tests" are just as valuable in general, so I'd encourage people to submit patches to the main Python test suite to add them.
Paul
On Jan 25, 2016, at 07:16 PM, Victor Stinner wrote:
Barry also wrote: "Did you address my suggestion on python-ideas to make the new C API optionally compiled in?"
Well, it is an option, but I would prefer to have the API for AST optimizer directly built in Python.
In my plan, it would be, but it would have to be enabled with a configure switch, and provisionally protected by an #ifdef.
And I agree to wait until fatoptimizer is proven to be faster than the regular CPython before taking a decision of my 3 PEPs (509, 510, 511).
+1 - and just to be clear, I hope you succeed beyond your wildest imagination. :) Cheers, -Barry
participants (16)
-
Andrew Barnert
-
Barry Warsaw
-
Brett Cannon
-
Chris Angelico
-
Glenn Linderman
-
INADA Naoki
-
Ludovic Gasc
-
Nick Coghlan
-
Paul Moore
-
Peter Ludemann
-
Ryan Gonzalez
-
Sjoerd Job Postmus
-
Stephen J. Turnbull
-
Sven R. Kunze
-
Terry Reedy
-
Victor Stinner