Why Python, Ruby, and Javascript are Slow
121–130 of 203 posts
Re: Why Python, Ruby, and Javascript are Slow
#122atoi(strchr(s, '-') + 1) What does this do? Finds the first instance of a -, and converts the remainder of a string to an int. 0 allocations, 0 copies. Doing this with 0 copies is pretty much impossible in Python, and probably in ruby and Javascript too. The copying could be avoided in non-idiomatic Python: int(buffer(s, s.find("-") + 1))
+s.substr(s.indexOf('-') + 1)Re: Why Python, Ruby, and Javascript are Slow
#123A nice talk. The punchline for me was: Things that take time •Hash table lookups •Allocations •Copying Interestingly, that's exactly how you write fast C++ code. His point is that languages like Python lack good API's for preallocating memory.
It's how you write fast algorithms in general, in any programming language. Minimize the number of reads and writes per iteration/recursion. In higher-level programming languages, it's just a bit harder to control the number of reads and writes because you're working at several layers of abstraction above them, and are concerned with solving higher-level problems. Use the language that provides the appropriate level…
The problem is that we haven't yet implemented those abstraction layers in this smart way - for example, Haskell can implement 'fusion' of multiple string operations so that they are merged together and executed without intermediate copies; and the abstraction layer for that is exactly as high-level as the Python examples in original poster's slides. Sure, it's objectively hard to change core Python like that - but it theoretically can be done, so it should&will be done.
Re: Why Python, Ruby, and Javascript are Slow
#124Re: Why Python, Ruby, and Javascript are Slow
#125Earlier quoted context omitted.
Yes, you could do a background thread, with some caveats: 1. On most current CPU's, this will cause really bad cache/memory thrashing, enough to probably impact the program. 2. This may actually cause significant slowdown, depending on how long it takes to optimize a given set of code (IE it may be better to spend 100ms paused optimizing than 5000ms in the background). This is, of course, a latency issue. 3. State of…
Background compilation in a separate thread actually works pretty well. IE9 has been shipping it with Chakra for a while, and Firefox is now getting it (and it improved the benchmarks a lot, especially on ARM).
I'm actually curious if you have any stats on how much of the time this is being done on actual busy machines where it's going to compete for L1/etc resources vs how often it's able to be offloaded onto an otherwise empty core.
IE i expect their to be a significant difference in the use cases for JIT's like PyPy, which are probably going to sit on shared servers that folks are trying to maximize utilization of, vs desktops where I imagine most browsing probably doesn't use all cores at 100%.
Re: Why Python, Ruby, and Javascript are Slow
#126Earlier quoted context omitted.
I would say that the difference between fast Python code and C is still quite large. - the syntax is less error-prone - ownership semantics are much clearer. You'll never segfault because you sent some memory into the wrong function - not as much detail is needed for memory layout, the JIT abstracts a lot of it away - there are high-level APIs handy - development and distribution are simpler with one less language -…
I'm interested in this discussion. Which of those issues could you dispense with using more modern APIs and idioms in C? Look at Objective C (mentally wipe off all the object goo), particular NSMutableString and NSMutableArray and NSMutableData, for examples of what I'm thinking about. The C syntax we're stuck with. But how big a deal is that syntax? Segfaults are mitigated if you don't expose pointers, except to the…
The woes of pointers (segfaults and security vulnerabilities) cannot be addressed in a library without a performance penalty. If you want a nice error message instead of a segfault or random memory overwrite you will have to pass around type information at run time. You could however have a production version of the stdlib that did not pass around type information, but that would only solve the issue at development time: the security vulnerabilities in production would still be there.
There is also an argument to be made that many of the optimizations mentioned in the presentation can be done automatically by the compiler/JIT. For example Javascript JITs already optimize small hash tables used as objects, since every Javascript object is a hash table. Load forwarding followed by code motion can remove unnecessary intermediate allocations. And the square example should have been written as:
[i*i for in in xrange(n)]
This can allocate the result list of the right size at the start of the allocation.Re: Why Python, Ruby, and Javascript are Slow
#127Meh, MEH. I'm almost never waiting on my python code. I'm waiting on network or disk or database or joe to check in his changes or etc. I'm sure there are people who do wait. But that's why numpy, c extensions, all the pypy, psycho, and similar things exist. Python and more broadly "scripting" languages are for speed of development. Something else can take on speed of execution faster than 90% of people need it to be…
Speed in Python (or Ruby, or JS) isn't a big deal... until it is. When that happens, would you rather have to switch over to C and glue the resulting binary in (assuming you're not using JS, in which case you're just SOL), or would you rather have a high performance API at your fingertips for optimization when you need it?
Re: Why Python, Ruby, and Javascript are Slow
#128Earlier quoted context omitted.
It's not an unresolved question whether idiomatic Python is slower than idiomatic C/C++ for solving comparable problems. Python is much, much slower than C.
This is completely true. It is indeed well known and common wisdom. However, I think the point the parent was trying to make is: Python is much slower than C and many other languages, however most of the time speed is unimportant. When it becomes important, there are many technologies to mitigate the problem in your "hot loops." If speed is your primary concern don't use Python et. al. If it isn't your main concern g…
There is an implicit assumption there that most of the time in your program that could be saved is spent in a small number of hot spots. This will often be true, but unfortunately it is not necessarily so.
This is a particular problem in languages like Python, which are useful (among other things) for their support for rapid prototyping and their easily readable code. All of that is lost if you can’t perform local optimizations to reach an acceptable level of performance, leaving a ground-up rewrite in a faster language like C as the next most likely strategy.
The kinds of techniques mentioned in the linked slides could help to create a middle ground that would be very useful for performance-sensitive projects that currently find themselves between a rock and a hard place.
Re: Why Python, Ruby, and Javascript are Slow
#129Earlier quoted context omitted.
@chadcf and @tptacek I was responding to @tptacek criticism of the parent not the deck. The deck is great and it mirrors the wisdom I have picked up from optimizing my own code over the years. I personally find it really frustrating not being able to easily pre-alloc lists in Python. I think that having better APIs would go a long way. As the deck says: "Line for line these languages are fast!" "We need better no-cop…
Forgive the naive question, but why not: l = [object()] * 100 Perhaps the difference is stack vs. heap?
object[0].x = 1
print object[1].x
> 1
Edit: On second read, it looks like you're asking something other than what I thought you were asking. Yes, you could create a list of 100 items and then replace its elements, but that's not idiomatic.Re: Why Python, Ruby, and Javascript are Slow
#130Related to this is the importance of deforestation. Some good links: * http://en.wikipedia.org/wiki/Deforestation_%28computer_scien... * http://www.haskell.org/haskellwiki/Short_cut_fusion Deforestation is basically eliminating intermediate data structures, which is similar to what the "int(s.split("-", 1)[1])" versus "atoi(strchr(s, '-') + 1)" slides are about. If you consider strings as just lists of characters, th…
Deforestation is easily done in lazy languages like Haskell. As for GC, it would be nice to have good real time GCs in runtimes.
Deforestation is /more useful/ in strict languages, because allocation of temporary structures costs more. So fusion on strict arrays is better than on lazy streams.
You just can't do it unless you can freely reorder multiple loops, and to do that you need a proof there are no side effects. Haskell just makes that trivial.