> Can someone with Python 3 handy compare there too?
C:\Python27\python -m timeit -n 1000000 -r 5 -v
"dict(a=1, b=2, c=3, d=4, e=5, f=6, g=7)"
raw times: 0.918 0.924 0.922 0.928 0.926
1000000 loops, best of 5: 0.918 usec per loop
C:\Python27\python -m timeit -n 1000000 -r 5 -v
"{'a':1, 'b':2, 'c':3, 'd':4, 'e':5, 'f':6, 'g':7}"
raw times: 0.48 0.49 0.482 0.496 0.497
1000000 loops, best of 5: 0.48 usec per loop
C:\Python32\python -m timeit -n 1000000 -r 5 -v
"dict(a=1, b=2, c=3, d=4, e=5, f=6, g=7)"
raw times: 0.898 0.891 0.892 0.899 0.891
1000000 loops, best of 5: 0.891 usec per loop
C:\Python32\python -m timeit -n 1000000 -r 5 -v
"{'a':1, 'b':2, 'c':3, 'd':4, 'e':5, 'f':6, 'g':7}"
raw times: 0.444 0.463 0.461 0.464 0.461
1000000 loops, best of 5: 0.444 usec per loop
C:\Python32_64\python -m timeit -n 1000000 -r 5 -v
"dict(a=1, b=2, c=3, d=4, e=5, f=6, g=7)"
raw times: 0.908 0.923 0.927 0.912 0.923
1000000 loops, best of 5: 0.908 usec per loop
C:\Python32_64\python -m timeit -n 1000000 -r 5 -v
"{'a':1, 'b':2, 'c':3, 'd':4, 'e':5, 'f':6, 'g':7}"
raw times: 0.484 0.446 0.501 0.45 0.442
1000000 loops, best of 5: 0.442 usec per loop
C:\Python33_64\python -m timeit -n 1000000 -r 5 -v
"dict(a=1, b=2, c=3, d=4, e=5, f=6, g=7)"
raw times: 1.02 1.07 1.03 1.11 1.07
1000000 loops, best of 5: 1.02 usec per loop
C:\Python33_64\python -m timeit -n 1000000 -r 5 -v
"{'a':1, 'b':2, 'c':3, 'd':4, 'e':5, 'f':6, 'g':7}"
raw times: 0.444 0.449 0.455 0.452 0.46
1000000 loops, best of 5: 0.444 usec per loop
Tested on Win7/64 bit. Python 2.7 is the 32-bit version, 3.2 is installed as 32-bit and 64-bit versions and 3.3 only as 64-bit version. In any case, the difference is even a bit stronger than what you experience and it seems that all versions perform roughly similar.
Uli
*************************************************************************** ***********
Domino Laser GmbH, Fangdieckstra e 75a, 22547 Hamburg, Deutschland
Gesch ftsf hrer: Hans Robert Dapprich, Amtsgericht Hamburg HR B62 932
*************************************************************************** ***********
Visit our website at http://www.dominolaser.com *************************************************************************** ***********
Diese E-Mail einschlie lich s mtlicher Anh nge ist nur f r den Adressaten bestimmt und kann vertrauliche Informationen enthalten. Bitte benachrichtigen Sie den Absender umgehend, falls Sie nicht der beabsichtigte Empf nger sein sollten. Die E-Mail ist in diesem Fall zu l schen und darf weder gelesen, weitergeleitet, ver ffentlicht oder anderweitig benutzt werden.
E-Mails k nnen durch Dritte gelesen werden und Viren sowie nichtautorisierte nderungen enthalten. Domino Laser GmbH ist f r diese Folgen nicht verantwortlich.
*************************************************************************** ***********
> On 14 November 2012 10:12, Chris Withers <ch...@simplistix.co.uk> wrote:
>> ...which made me a little sad
> Why did it make you sad? dict() takes 0.2µs, {} takes 0.04µs. In other
> words: you can run dict() _five million_ times per second, and {}
> twenty-five million times per second. That is 'a lot' and 'a lot'. It
> also means you are unlikely to notice the difference in real-world
> code. Just use the one you feel is clearer in the situation, and don't
> worry about micro-optimalization.
I'm inclined to agree, but it makes me sad for two reasons:
- it's something that people get hung up on, for better or worse. (if it wasn't, Doug wouldn't have written his article)
- it can make a difference, for example setting up a dict with many keys at the core of a type loop.
Without looking at implementation, they should logically perform the same...
> a_dict = dict(
> x = 1,
> y = 2,
> z = 3,
> ...
> )
> What can we do to speed up the former case?
It should be possible to special-case it. Rather than creating
a new dictionary from scratch, one could try to have the new dictionary
the same size as the original one, and copy all entries.
I also wonder whether the PyArg_ValidateKeywordArguments call is really
necessary: if this is not a proper keyword dictionary, dict creation
could still proceed in a reasonable way.
I don't know how much this would gain, though. You still have to
create two dictionary objects. For a better speedup, try
> On 14/11/2012 09:58, Merlijn van Deen wrote: > > On 14 November 2012 10:12, Chris Withers <ch...@simplistix.co.uk> > > wrote: > >> ...which made me a little sad
> > Why did it make you sad? dict() takes 0.2µs, {} takes 0.04µs. In > > other words: you can run dict() _five million_ times per second, > > and {} twenty-five million times per second. That is 'a lot' and 'a > > lot'. It also means you are unlikely to notice the difference in > > real-world code. Just use the one you feel is clearer in the > > situation, and don't worry about micro-optimalization.
> I'm inclined to agree, but it makes me sad for two reasons:
> - it's something that people get hung up on, for better or worse. (if > it wasn't, Doug wouldn't have written his article)
> - it can make a difference, for example setting up a dict with many > keys at the core of a type loop.
Well, please post examples of *real-world* use cases where it makes a difference. Otherwise, you're asking us to add hacks to the implementation just to make you feel good, which is quite unacceptable.
> On 14/11/2012 09:58, Merlijn van Deen wrote: >> On 14 November 2012 10:12, Chris Withers <ch...@simplistix.co.uk> wrote: >>> ...which made me a little sad
>> Why did it make you sad? dict() takes 0.2µs, {} takes 0.04µs. In other >> words: you can run dict() _five million_ times per second, and {} >> twenty-five million times per second. That is 'a lot' and 'a lot'. It >> also means you are unlikely to notice the difference in real-world >> code. Just use the one you feel is clearer in the situation, and don't >> worry about micro-optimalization.
> I'm inclined to agree, but it makes me sad for two reasons:
> - it's something that people get hung up on, for better or worse. (if it > wasn't, Doug wouldn't have written his article)
People get hung up on all sorts of things. I would hate to think we would complicate the implementation to pander to pointless micro-optimization. I'm sure that there are many far more important things than this.
> - it can make a difference, for example setting up a dict with many keys >at the core of a type loop.
Ah yes, the semi-mythical "tight loop".
I've never come across one of these tight loops that creates a dict with many keys in a tight loop, and then apparently fails to actually use it for anything useful. For if it did, surely the actual work done with the dict is going to outweigh the setup cost for all but the most trivial applications. I find it hard to get uptight about a small inefficiency in trivial applications that don't do much.
Show me a non-toy use-case where creating dicts is an actual bottleneck, and I'll revise my position.
> Without looking at implementation, they should logically perform the same...
I disagree. Calling dict() has to do a name lookup, and then a function call. That alone is almost 2.5 times as expensive as creating a dict literal on my machine:
[steve@ando ~]$ python3.3 -m timeit "d = {}" 10000000 loops, best of 3: 0.17 usec per loop [steve@ando ~]$ python3.3 -m timeit "d = dict()" 1000000 loops, best of 3: 0.416 usec per loop
Then you have the function call itself, which engages the argument parsing mechanism, which does more work than dict literal syntax. For example, it checks for duplicate keyword arguments, while dict literals happily accept duplicate keys.
It's hardly a surprise that dict() is slower than {}.
On Wed, Nov 14, 2012 at 8:12 PM, Chris Withers <ch...@simplistix.co.uk> wrote:
> I suspect I'm not the only one who finds:
> a_dict = dict(
> x = 1,
> y = 2,
> z = 3,
> ...
> )
> ...easier to read than:
> a_dict = {
> 'x':1,
> 'y':2,
> 'z':3,
> ...
> }
> What can we do to speed up the former case?
Perhaps an alternative question: What can be done to make the latter
less unpalatable? I personally prefer dict literal syntax to a dict
constructor call, but no doubt there are a number of people who feel
as you do. In what way(s) do you find the literal syntax less
readable, and can some simple (and backward-compatible) enhancements
help that?
I've seen criticisms (though I don't recall where) of Python,
comparing it to JavaScript/ECMAScript, that complain of the need to
quote the keys. IMO this is a worthwhile downside, as it allows you to
use variables as the keys, rather than requiring (effectively) literal
strings. But it does make a dict literal that much more "noisy" than
the constructor.
> Zitat von Chris Withers <ch...@simplistix.co.uk>:
>> a_dict = dict(
>> x = 1,
>> y = 2,
>> z = 3,
>> ...
>> )
>> What can we do to speed up the former case?
> It should be possible to special-case it. Rather than creating
> a new dictionary from scratch, one could try to have the new dictionary
> the same size as the original one, and copy all entries.
> I also wonder whether the PyArg_ValidateKeywordArguments call is really
> necessary: if this is not a proper keyword dictionary, dict creation
> could still proceed in a reasonable way.
In the common case PyArg_ValidateKeywordArguments should be a simple check.
> Perhaps an alternative question: What can be done to make the latter
> less unpalatable? I personally prefer dict literal syntax to a dict
> constructor call, but no doubt there are a number of people who feel
> as you do. In what way(s) do you find the literal syntax less
> readable, and can some simple (and backward-compatible) enhancements
> help that?
> I've seen criticisms (though I don't recall where) of Python,
> comparing it to JavaScript/ECMAScript, that complain of the need to
> quote the keys. IMO this is a worthwhile downside, as it allows you to
> use variables as the keys, rather than requiring (effectively) literal
> strings. But it does make a dict literal that much more "noisy" than
> the constructor.
If that bothers you in a specific case, I recommend using the constructor
instead of a literal.
On Wed, Nov 14, 2012 at 3:12 AM, Chris Withers <ch...@simplistix.co.uk> wrote:
> Hi All,
> A colleague pointed me at Doug's excellent article here:
> ...which made me a little sad, I suspect I'm not the only one who finds:
> a_dict = dict(
> x = 1,
> y = 2,
> z = 3,
> ...
> )
> ...easier to read than:
> a_dict = {
> 'x':1,
> 'y':2,
> 'z':3,
> ...
> }
Hey, it makes me a little sad that dict breaks convention by allowing
the use of unquoted characters (which everywhere else looks like
variable names) just for a silly typing optimization.
On Wed, Nov 14, 2012 at 10:12:54AM -0600, Mark Adam <dreamingforw...@gmail.com> wrote:
> On Wed, Nov 14, 2012 at 3:12 AM, Chris Withers <ch...@simplistix.co.uk> wrote:
> > Hi All,
> > A colleague pointed me at Doug's excellent article here:
> > ...which made me a little sad, I suspect I'm not the only one who finds:
> > a_dict = dict(
> > x = 1,
> > y = 2,
> > z = 3,
> > ...
> > )
> Hey, it makes me a little sad that dict breaks convention by allowing
> the use of unquoted characters (which everywhere else looks like
> variable names) just for a silly typing optimization.
It doesn't. It's a call (function call or or a class instantiation)
and it's not dict-specific: function(a=1, b=None)...
On Wed, Nov 14, 2012 at 10:12 AM, Mark Adam <dreamingforw...@gmail.com> wrote:
> On Wed, Nov 14, 2012 at 3:12 AM, Chris Withers <ch...@simplistix.co.uk> wrote:
>> Hi All,
>> A colleague pointed me at Doug's excellent article here:
>> ...which made me a little sad, I suspect I'm not the only one who finds:
>> a_dict = dict(
>> x = 1,
>> y = 2,
>> z = 3,
>> ...
>> )
> Hey, it makes me a little sad that dict breaks convention by allowing
> the use of unquoted characters (which everywhere else looks like
> variable names) just for a silly typing optimization.
On Wed, Nov 14, 2012 at 11:00 AM, Brian Curtin <br...@python.org> wrote:
> On Wed, Nov 14, 2012 at 10:12 AM, Mark Adam <dreamingforw...@gmail.com> wrote:
>> On Wed, Nov 14, 2012 at 3:12 AM, Chris Withers <ch...@simplistix.co.uk> wrote:
>>> Hi All,
>>> A colleague pointed me at Doug's excellent article here:
>>> ...which made me a little sad, I suspect I'm not the only one who finds:
>>> a_dict = dict(
>>> x = 1,
>>> y = 2,
>>> z = 3,
>>> ...
>>> )
>> Hey, it makes me a little sad that dict breaks convention by allowing
>> the use of unquoted characters (which everywhere else looks like
>> variable names) just for a silly typing optimization.
> What convention and typing optimization is this? I hope you aren't
> suggesting it should be dict("x"=1) or dict("x":1)?
Try the canonical {'x':1}. Only dict allows the special
initialization above. Other collections require an iterable. I'm guessing
**kwargs initialization was only used because it is so simple to
implement, but that's not necessarily a heuristic for good language design.
On Wed, 14 Nov 2012 11:10:15 -0600, Mark Adam <dreamingforw...@gmail.com> wrote:
> On Wed, Nov 14, 2012 at 11:00 AM, Brian Curtin <br...@python.org> wrote:
> > On Wed, Nov 14, 2012 at 10:12 AM, Mark Adam <dreamingforw...@gmail.com> wrote:
> >> On Wed, Nov 14, 2012 at 3:12 AM, Chris Withers <ch...@simplistix.co.uk> wrote:
> >>> Hi All,
> >>> A colleague pointed me at Doug's excellent article here:
> >>> ...which made me a little sad, I suspect I'm not the only one who finds:
> >>> a_dict = dict(
> >>> x = 1,
> >>> y = 2,
> >>> z = 3,
> >>> ...
> >>> )
> >> Hey, it makes me a little sad that dict breaks convention by allowing
> >> the use of unquoted characters (which everywhere else looks like
> >> variable names) just for a silly typing optimization.
> > What convention and typing optimization is this? I hope you aren't
> > suggesting it should be dict("x"=1) or dict("x":1)?
> Try the canonical {'x':1}. Only dict allows the special
> initialization above. Other collections require an iterable. I'm guessing
> **kwargs initialization was only used because it is so simple to
> implement, but that's not necessarily a heuristic for good language design.
Maybe it's not good design, but I'll bet you that if it didn't do that,
there would be lots of instances of this scattered around various
codebases:
On Wed, Nov 14, 2012 at 11:27 AM, R. David Murray <rdmur...@bitdance.com> wrote:
> Maybe it's not good design, but I'll bet you that if it didn't do that,
> there would be lots of instances of this scattered around various
> codebases:
> def makedict(**kw):
> return kw
Now that's a good solution and probably solves the OP speed problem.
> Try the canonical {'x':1}. Only dict allows the special
> initialization above. Other collections require an iterable.
Other collections don't have a choice, because it would often be
ambiguous. Dicts do not have that issue.
> I'm guessing
> **kwargs initialization was only used because it is so simple to
> implement, but that's not necessarily a heuristic for good language design.
On Wed, Nov 14, 2012 at 12:12 PM, Xavier Morel <catch-...@masklinn.net> wrote:
> On 2012-11-14, at 18:10 , Mark Adam wrote:
>> Try the canonical {'x':1}. Only dict allows the special
>> initialization above. Other collections require an iterable.
> Other collections don't have a choice, because it would often be
> ambiguous. Dicts do not have that issue.
mkay....
>> I'm guessing
>> **kwargs initialization was only used because it is so simple to
>> implement, but that's not necessarily a heuristic for good language design.
> In this case it very much is, it permits easily merging two dicts in a
> single expression or cloning-with-replacement. It also mirrors the
> signature of dict.update which I think is a Good Thing.
Merging of two dicts is done with dict.update. How do you do it on
initialization? This doesn't make sense.
On Thu, Nov 15, 2012 at 12:18:38AM +1100, Chris Angelico <ros...@gmail.com> wrote:
> On Wed, Nov 14, 2012 at 8:12 PM, Chris Withers <ch...@simplistix.co.uk> wrote:
> > I suspect I'm not the only one who finds:
> > a_dict = dict(
> > x = 1,
> > y = 2,
> > z = 3,
> > ...
> > )
> Perhaps an alternative question: What can be done to make the latter
> less unpalatable? I personally prefer dict literal syntax to a dict
> constructor call, but no doubt there are a number of people who feel
> as you do. In what way(s) do you find the literal syntax less
> readable, and can some simple (and backward-compatible) enhancements
> help that?
> I've seen criticisms (though I don't recall where) of Python,
> comparing it to JavaScript/ECMAScript, that complain of the need to
> quote the keys. IMO this is a worthwhile downside, as it allows you to
> use variables as the keys, rather than requiring (effectively) literal
> strings. But it does make a dict literal that much more "noisy" than
> the constructor.
On the other had it's more powerful. You can write {'class': 'foo'}
but cannot dict(class='bar'). {1: '1'} but not dict(1='1').