[Python-Dev] performance

Neal Norwitz nnorwitz at gmail.com
Sun Aug 24 19:25:55 CEST 2008


Thanks Antoine!

On Sun, Aug 24, 2008 at 5:58 AM, Antoine Pitrou <solipsis at pitrou.net> wrote:
> Neal Norwitz <nnorwitz <at> gmail.com> writes:
>> Can someone (else) compare performance of 2.5, 2.6, and 3.0?
>
> Tests done on a 32-bit Linux installation on an Athlon 3600+ X2. Compiled with
> gcc in UCS2 mode.
>
> pystone
> -------
>
> - 2.5: 43859.6 pystones/second
> - 2.6: 42016.8 pystones/second
> - 3.0: 38759.7 pystones/second

So 3.0 is about 10% slower than 2.x.  Given all the changes, that
doesn't seem too bad.  Though, see below.  It looks like at least
class attribute lookup is much, much slower.  Can you investigate some
of these and file bugs as appropriate?

> richards.py
> -----------
>
> (roughly, richards is an object-oriented method-calling benchmark)
>
> - 2.5: 770.54 ms per iteration
> - 2.6: 572.84 ms per iteration
> - 3.0: 566.69 ms per iteration

I'm a little concerned about why the big change here.  Though if I'm
reading this right it's a speed up...or am I just being optimistic?

The only things I remember that changed between 2.5 and 2.6 that might
affect this (without looking at any code) were:  1) Armin's method
caching, and 2) the slowdown to isinstance/issubclass which has a
release blocker:  http://bugs.python.org/issue2534

Can you dig into this and see what caused the slowdown?

>
> stringbench
> -----------
>
> - 2.5: unicode: 265.84 s / bytes: 180.50 s
> - 2.6: unicode: 256.22 s / bytes: 184.45 s
> - 3.0: unicode: 248.07 s / bytes: not tested
>
> pybench: 2.6 vs. 2.5
> --------------------
>
> "this" is 2.6, "other" is 2.5.

Hopefully anything >10% is a real change and not just noise.

> Test                             minimum run-time        average  run-time
>                                 this    other   diff    this    other   diff
> -------------------------------------------------------------------------------
>          BuiltinFunctionCalls:   177ms   181ms   -2.2%   178ms   182ms   -2.1%
>           BuiltinMethodLookup:   157ms   177ms  -11.1%   158ms   177ms  -11.0%

Maybe explained by Armin's patch.

>                 CompareFloats:   171ms   171ms   -0.3%   171ms   171ms   -0.3%
>         CompareFloatsIntegers:   158ms   162ms   -2.1%   160ms   167ms   -4.8%
>               CompareIntegers:   208ms   208ms   -0.0%   209ms   209ms   -0.3%
>        CompareInternedStrings:   189ms   183ms   +3.4%   189ms   184ms   +2.7%
>                  CompareLongs:   154ms   154ms   -0.2%   154ms   154ms   -0.2%
>                CompareStrings:   162ms   159ms   +1.7%   163ms   159ms   +2.5%
>                CompareUnicode:   144ms   149ms   -3.6%   144ms   152ms   -5.0%
>    ComplexPythonFunctionCalls:   173ms   242ms  -28.5%   176ms   243ms  -27.6%

Maybe explained by Armin's patch.

>                 ConcatStrings:   196ms   198ms   -0.9%   203ms   200ms   +1.4%
>                 ConcatUnicode:   153ms   151ms   +1.5%   155ms   157ms   -1.5%
>               CreateInstances:   172ms   169ms   +1.5%   173ms   170ms   +1.4%
>            CreateNewInstances:   131ms   148ms  -11.6%   132ms   151ms  -12.2%

Maybe explained by Armin's patch.

>       CreateStringsWithConcat:   209ms   206ms   +1.4%   209ms   208ms   +0.8%
>       CreateUnicodeWithConcat:   128ms   124ms   +3.7%   129ms   124ms   +3.4%
>                  DictCreation:   115ms   149ms  -22.8%   116ms   150ms  -22.8%

Why?  What changed?

>             DictWithFloatKeys:   208ms   207ms   +0.4%   208ms   208ms   +0.0%
>           DictWithIntegerKeys:   173ms   173ms   -0.0%   174ms   173ms   +0.5%
>            DictWithStringKeys:   162ms   162ms   -0.1%   162ms   162ms   +0.1%
>                      ForLoops:   181ms   181ms   -0.2%   181ms   182ms   -0.2%
>                    IfThenElse:   169ms   168ms   +0.2%   169ms   169ms   -0.2%
>                   ListSlicing:   109ms   108ms   +0.2%   109ms   109ms   +0.1%
>                NestedForLoops:   198ms   197ms   +0.2%   198ms   197ms   +0.1%
>          NormalClassAttribute:   176ms   172ms   +2.0%   176ms   173ms   +1.7%
>       NormalInstanceAttribute:   162ms   161ms   +1.0%   163ms   161ms   +1.1%
>           PythonFunctionCalls:   161ms   151ms   +6.6%   162ms   153ms   +6.0%
>             PythonMethodCalls:   188ms   189ms   -0.7%   189ms   193ms   -2.0%
>                     Recursion:   235ms   230ms   +2.2%   236ms   233ms   +1.2%
>                  SecondImport:   113ms   114ms   -1.0%   115ms   115ms   +0.0%
>           SecondPackageImport:   120ms   116ms   +3.6%   120ms   117ms   +2.9%
>         SecondSubmoduleImport:   154ms   146ms   +6.0%   156ms   148ms   +5.7%
>       SimpleComplexArithmetic:   163ms   151ms   +8.3%   163ms   151ms   +8.6%
>        SimpleDictManipulation:   177ms   173ms   +2.6%   180ms   174ms   +3.2%
>         SimpleFloatArithmetic:   169ms   164ms   +3.0%   169ms   166ms   +2.2%
>      SimpleIntFloatArithmetic:   153ms   152ms   +1.2%   156ms   153ms   +1.8%
>       SimpleIntegerArithmetic:   156ms   152ms   +2.5%   156ms   153ms   +2.0%
>        SimpleListManipulation:   156ms   158ms   -1.0%   157ms   158ms   -0.5%
>          SimpleLongArithmetic:   159ms   150ms   +6.1%   161ms   151ms   +6.3%
>                    SmallLists:   156ms   154ms   +1.1%   160ms   155ms   +3.0%
>                   SmallTuples:   156ms   155ms   +0.4%   157ms   156ms   +0.8%
>         SpecialClassAttribute:   173ms   172ms   +0.6%   173ms   172ms   +0.7%
>      SpecialInstanceAttribute:   202ms   198ms   +2.4%   203ms   199ms   +2.2%
>                StringMappings:   164ms   170ms   -3.2%   165ms   171ms   -3.9%
>              StringPredicates:   160ms   185ms  -13.6%   160ms   186ms  -13.9%

Maybe explained by Armin's patch.

>                 StringSlicing:   169ms   178ms   -5.3%   174ms   180ms   -3.4%
>                     TryExcept:   181ms   184ms   -1.5%   181ms   184ms   -1.5%
>                    TryFinally:   157ms   158ms   -0.3%   159ms   161ms   -1.2%
>                TryRaiseExcept:   183ms   122ms  +49.6%   184ms   124ms  +48.2%

Whoa, that's a big slowdown.  I wonder if it's consistent?

>                  TupleSlicing:   142ms   140ms   +1.5%   144ms   141ms   +2.0%
>               UnicodeMappings:   198ms   190ms   +4.1%   198ms   190ms   +4.1%
>             UnicodePredicates:   157ms   175ms  -10.2%   157ms   176ms  -10.6%

?

>             UnicodeProperties:   161ms   161ms   +0.1%   162ms   170ms   -5.0%
>                UnicodeSlicing:   148ms   153ms   -3.3%   151ms   155ms   -2.6%
>                   WithFinally:   191ms   203ms   -5.9%   193ms   208ms   -7.5%
>               WithRaiseExcept:   151ms   160ms   -5.8%   152ms   167ms   -9.0%
> -------------------------------------------------------------------------------
> Totals:                          9287ms  9363ms   -0.8%  9351ms  9455ms   -1.1%
>
>
> pybench: 3.0
> ------------
>
> Not entirely comparable with the above since some tests disappeared.
>
> Test                             minimum  average  operation  overhead
> -------------------------------------------------------------------------------
>          BuiltinFunctionCalls:    134ms    134ms    0.26us    0.631ms
>           BuiltinMethodLookup:    127ms    127ms    0.12us    0.738ms
>                 CompareFloats:    174ms    174ms    0.14us    0.845ms
>         CompareFloatsIntegers:    274ms    274ms    0.30us    0.630ms

Much slower, but probably due to switch from int -> long.  There could
be potential for optimizing this case.

>               CompareIntegers:    277ms    277ms    0.15us    1.272ms

That's really slow!

>        CompareInternedStrings:    261ms    261ms    0.17us    3.201ms

Much slower, but probably str -> unicode conversion.

>                  CompareLongs:    162ms    162ms    0.15us    0.736ms

But this is comparable to 2.x.  I don't understand that?

>                CompareStrings:    171ms    173ms    0.17us    2.188ms
>    ComplexPythonFunctionCalls:    172ms    178ms    0.89us    1.073ms
>                 ConcatStrings:    260ms    273ms    0.55us    1.222ms

This is much slower in 3.0, even taking into account str -> unicode?

>               CreateInstances:    178ms    178ms    1.59us    0.944ms
>            CreateNewInstances:    133ms    135ms    1.61us    0.759ms
>       CreateStringsWithConcat:    253ms    256ms    0.26us    2.127ms
>                  DictCreation:    118ms    118ms    0.29us    0.845ms
>             DictWithFloatKeys:    207ms    215ms    0.24us    1.593ms
>           DictWithIntegerKeys:    174ms    176ms    0.15us    2.132ms
>            DictWithStringKeys:    158ms    158ms    0.13us    2.127ms
>                      ForLoops:    188ms    188ms    7.51us    0.097ms
>                    IfThenElse:    212ms    212ms    0.16us    1.597ms

Slower?

>                   ListSlicing:    111ms    111ms    7.96us    0.165ms
>                NestedForLoops:    218ms    220ms    0.15us    0.001ms
>          NormalClassAttribute:    339ms    340ms    0.28us    1.111ms

Over twice as slow?

>       NormalInstanceAttribute:    186ms    186ms    0.16us    1.116ms
>           PythonFunctionCalls:    156ms    158ms    0.48us    0.633ms
>             PythonMethodCalls:    200ms    201ms    0.89us    0.374ms
>                     Recursion:    259ms    260ms    5.21us    1.059ms
>                  SecondImport:    128ms    128ms    1.28us    0.417ms
>           SecondPackageImport:    140ms    143ms    1.43us    0.417ms
>         SecondSubmoduleImport:    200ms    200ms    2.00us    0.417ms
>       SimpleComplexArithmetic:    142ms    144ms    0.16us    0.844ms
>        SimpleDictManipulation:    280ms    285ms    0.24us    1.059ms

Slower.  str -> unicode?

>         SimpleFloatArithmetic:    161ms    161ms    0.12us    1.275ms
>      SimpleIntFloatArithmetic:    199ms    213ms    0.16us    1.272ms
>       SimpleIntegerArithmetic:    200ms    209ms    0.16us    1.301ms
>        SimpleListManipulation:    165ms    166ms    0.14us    1.379ms
>          SimpleLongArithmetic:    132ms    137ms    0.21us    0.630ms
>                    SmallLists:    188ms    191ms    0.28us    0.844ms
>                   SmallTuples:    197ms    199ms    0.37us    0.951ms
>         SpecialClassAttribute:    534ms    535ms    0.45us    1.121ms

~4x slower!

>      SpecialInstanceAttribute:    185ms    186ms    0.15us    1.125ms
>                StringMappings:    471ms    471ms    1.87us    0.884ms

~3X slower.

>              StringPredicates:    190ms    191ms    0.27us    4.315ms
>                 StringSlicing:    285ms    290ms    0.52us    1.881ms
>                     TryExcept:    182ms    182ms    0.08us    1.663ms
>                    TryFinally:    134ms    136ms    0.85us    0.882ms
>                TryRaiseExcept:    137ms    138ms    2.15us    0.885ms
>                  TupleSlicing:    202ms    204ms    0.78us    0.110ms
>                   WithFinally:    185ms    188ms    1.18us    0.881ms
>               WithRaiseExcept:    274ms    275ms    3.44us    1.105ms

Slower.

> -------------------------------------------------------------------------------
> Totals:                          10011ms  10120ms
>
>
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> http://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe: http://mail.python.org/mailman/options/python-dev/nnorwitz%40gmail.com
>


More information about the Python-Dev mailing list