5 ms·
also says this syntax is compatible with python which is not really true. if you have this in python: { key: "value", dr_nic: "The Comedian",
by jiaaro 16y ago
also says this syntax is compatible with python which is not really true. if you have this in python:
{
key: "value",
dr_nic: "The Comedian",
ttl: 42
}
python will expect there to be a variable called 'key', one called 'dr_nic', and one called 'ttl'. If you intend to do
d['ttl']
you'll need to create a hash using a literal string
- j_baker 16y agoYou don't necessarily have to create a hash using a literal string. You can also do this: dict( key="value", dr_nic="The Comedian", ttl=42 ) ...but that is a bit different syntax.
- cma 16y agoIt will also make your code drastically slower.
- baddox 16y agoSlower than what alternative?
- SoftwareMaven 16y agoSlower than my_dict = { "foo": 1, "baz": 2 } I was unaware that there was a difference in performance, but a quick timing check shows that it takes about twice as long to create a dictionary with 7 items using dict() than using {}. It makes sense when I stop to think about what the code would have to do, though.
- baddox 16y agoYou're right; I'm seeing dict() with explicit kwargs taking 3 times as long as a literal. My unscientific and non-rigorous benchmarks tell me that the construction and unpacking of the kwargs in the dict() call are the cause of most of the slowdown. With the time it takes to assign with a literal normalized to 1, I'm seeing dict(kwargs) (with kwargs created before the benchmark) take 2 and dict(key_1=val_1, key_2=val_2, etc.) take 3.
- j_baker 16y agoUnpacking kwargs is pretty much equivalent to building a dict. The major slowdown is 1) looking up dict and 2) calling a function: >>> def dict1(): ... {"a" : 1, "b" : 2} ... >>> from dis import dis >>> dis(dict1) 2 0 BUILD_MAP 2 3 LOAD_CONST 1 (1) 6 LOAD_CONST 2 ('a') 9 STORE_MAP 10 LOAD_CONST 3 (2) 13 LOAD_CONST 4 ('b') 16 STORE_MAP 17 POP_TOP 18 LOAD_CONST 0 (None) 21 RETURN_VALUE >>> def dict2(): ... dict(a=1, b=2) ... >>> dis(dict2) 2 0 LOAD_GLOBAL 0 (dict) 3 LOAD_CONST 1 ('a') 6 LOAD_CONST 2 (1) 9 LOAD_CONST 3 ('b') 12 LOAD_CONST 4 (2) 15 CALL_FUNCTION 512 18 POP_TOP 19 LOAD_CONST 0 (None) 22 RETURN_VALUE Given that, I'd assume that the overhead doesn't grow as the dict grows.
- cma 16y agoAs python runtimes/JITs get better and better, the literal version could get relatively faster, since static assertions can potentially more easily be made about it; whereas the global 'dict' could be replaced with anything, requiring much more sophistication. Say you use a dict in a non-mutating manner, it is made up of string literals only, and you construct it within a loop; it could be able to be pulled out as an invariant, the same could be true of the function-call case, but potentially not as easily.
- barrkel 16y agoIn optimizing a dynamic language, the problem of a symbol being replaced like this is no big deal; it's all but the expected norm, and inline caching ought to take care of it. On invariant code motion: it tends not to be a big win because programmers usually move obvious big code out of loops explicitly. They do that because relying on a compiler optimization to do it is unpredictable; you may accidentally trigger a wall in your optimizer's ability to analyze your code as it grows more complex over time. But we really are arguing over small potatoes here.
- j_baker 16y agoSlower yes, but not drastically: % python -m timeit '{"key": "value", "dr_nic": "The Comedian", "ttl": 42}' 1000000 loops, best of 3: 0.296 usec per loop % python -m timeit 'dict(key="value", dr_nic="The Comedian", ttl=42)' 1000000 loops, best of 3: 0.771 usec per loop There are far better ways to make code faster than worrying about the extra fraction of a microsecond you're spending calling dict rather than using the literal syntax.
- Ingaz 16y agoYeah. I always do in such way. And I will continue even if it's a bit slower =)
- pyre 16y agoYea. So they've move away from the Perl-like 'rocket' syntax to a more JavaScript/Python-like syntax. Ruby+Python hackers will rejoice while Perl+Ruby hackers will pout. This isn't necessarily some 'huge' win. [Though I guess it could be a 'win' for Rails hackers since they are likely to just be Ruby/Rails+JavaScript hackers.]
- phaylon 16y agoAs a Perl developer I'd say »More power to them.« Also, since Perl's => is basically a comma operator that turns a bareword on its left into a string, I'd say Ruby's move is a step away from Perl regarding syntax, but a step towards Perl regarding functionality. Anyway, as a non-Ruby developer I can appreciate the move. Also reminds a bit of some Scheme's ability to prefix and postfix symbols with »:«.
- jerf 16y agoI am not a Ruby programmer. What's the syntax for using a variable as the key, which is actually synonymous with the Python code?
- deleted 16y ago[deleted]
- j_baker 16y agoIt would be something like this: >> a = :foobar => :foobar >> {a => 1} => {:foobar=>1}