TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Python Patterns - An Optimization Anecdote

74 pointsby niyazpkover 14 years ago

8 comments

neneover 14 years ago
I decided to try writing the same thing in JavaScript and discovered something really strange.<p>My first idea was:<p><pre><code> numbers.map(function(x){return String.fromCharCode(x);}).join(""); </code></pre> This was pretty fast already, but why not eliminate the anonymous function completely and pass String.fromCharCode directly to map():<p><pre><code> numbers.map(String.fromCharCode).join(""); </code></pre> I timed it and... ...this was ~100 times slower than the previous version. WTF!<p>Somehow passing this native function directly to Array.map() is way slower than wrapping it inside another function and passing that to Array.map().<p>I have tested it so far in Chrome, Firefox and Opera - the results are the same. I also tried forEach(), which behaves similarly.<p>Does anybody have an idea why this is so?<p>Update: I tried the same with Math.round and Math.sin, and with these the results were as one would expect: passing the function to Array.map() directly was a little bit faster than using intermediate anonymous function. So it seems the problem is with String.fromCharCode specifically.
评论 #1860516 未加载
评论 #1859959 未加载
评论 #1860000 未加载
edanmover 14 years ago
I once found myself writing a python program to calculate Poker hands. It was pretty fun to write - it generated, for any given hand you hold, every possible way the game can go forward, and generated statistics about how many times you win (against 1 opponent only, who could be holding anything.)<p>The program initially ran for 20 minutes on each hand. I worked a day on optimizing it, and got it down to around 1-2 minutes per hand, so I learned a few tricks to make things quicker. Lessons learned:<p>1. Local lookups are <i>much</i> faster.<p>2. Anything that you can somehow offload to a c-loop, makes things much faster.<p>3. Surprisingly, the fastest construct for building a new list was always list comprehension (e.g. [x for x in calc(l) or whatever.) This was far faster than a regular ol' for-loop, of course, but was also faster than using map's and reduce's.
评论 #1860213 未加载
danielhover 14 years ago
It's a whole different story if the input gets longer and the quadratic complexity kicks in. Just change the testdata like this:<p><pre><code> testdata = range(256)*100 </code></pre> Result:<p><pre><code> f1 5.539 f2 40.747 f3 5.072 f4 5.311 f5 0.068 f6 3.304 f7 1.431</code></pre>
rix0rover 14 years ago
The first thing that stuck out to me like a sore thumb was the string-concatenation-in-a-loop. Though the author was aware of its consequences he only addressed it late in the article, optimizing relatively trivial stuff like variable lookups first. And then he did so in a rather strange way, instead of adding string fragments to a list and then join()ing them.<p>Not sure how fast that loop would be in Python compared to the implied loop&#38;join but I sure would have liked to see them compared.
评论 #1859670 未加载
评论 #1859800 未加载
评论 #1860380 未加载
codefisherover 14 years ago
For those interested, the author of this was actually Guido himself.<p>I would have used "".join(map(chr, list)) myself. But I am not sure that was support in the version of python available at the time. It is equivalent to f6.<p>To some of those talking about the dynamic nature of python means you have to look up chr every time, there is a way to stop that, see this project <a href="http://github.com/rfk/promise/" rel="nofollow">http://github.com/rfk/promise/</a>
RyanMcGrealover 14 years ago
Why not just:<p><pre><code> def f(list): return ''.join([chr(l) for l in list])</code></pre>
评论 #1860089 未加载
评论 #1860179 未加载
评论 #1860066 未加载
rmcover 14 years ago
Incidentally, are there any programmes that can scan your python functions and suggest improvements that are in this article? e.g. any programme that'll suggest referencing global names to the local namespace, using map etc.?
Devilboyover 14 years ago
I hope that one day soon our compilers will be smart enough to optimize simple things like this automatically, so we can focus more on writing for clarity. This seems like exactly the kind of thing a next-gen compiler should be able to optimize.
评论 #1859657 未加载