views:

196

answers:

8

Hi,

I now primarily write in python, however I am looking for a language that is more thread friendly (not JAVA,C#,C or C++).

Python's threads are good when they are IO bound but it's coming up short when I am doing something CPU intensive.

Any ideas?

Thanks, James

A: 

to overcome GIL, you can try interpreting python language with jython instead of cpython

mykhal
Thanks but I am trying to move away from Java. Looking for a new language now.... (although PyPy looks promising)
James
@user386129 well, jython is java to a similar extent as cpython is c :)
mykhal
Also in testing jython (some small test code) I see it's slower than cPython
James
@James right, unless you're using threads on multi-core CPU
mykhal
+1  A: 

Python falls short when it comes to CPU intensive tasks because Python isn't a very efficient language. Many "dynamic" languages have that problem, since the compiler is limited in what it can assume about the program at compile-time. Method-calls, for example, may have to be looked up every single time in case someone has replaced the method on the object between each invokation.

I would recommend that you take a look at Erlang, even though it probably isn't "Pythonic" in your sense of the word. :-)

JesperE
+1 for Erlang. The syntax and bind-once variables can be a bit surprising initially though.
Manoj Govindan
Pythonic meaning that it's a fun language to write in. Is Erlang compiled? Also how do the processes compare to threads?
James
Not sure I'd choose Erlang for a compute intensive application.
High Performance Mark
@Mark why wouldn't you use Erlang?
James
@James: Pythonic == Fun? That's probably the most meaningless definition of "Pythonic" you can come up with.
JesperE
@James: Yes, Erlang compiles to native code (at least for x86 and a couple of other architectures). Erlang processes are dynamically scheduled on top of a number of native threads; which means that you can use very many Erlang processes without consuming any significant kernel resources.
JesperE
Erlang encourages using concurrent processes for just about anything, and since inter-process communication is independent of the physical hardware (i.e. which machine the process is running on), Erlang applications scale really easily.
JesperE
@High Performance: Why not? If the problem can be parallelized, Erlang is one of the best options for it.
musicfreak
+6  A: 

Clojure is pretty fun, if you're into that sort of thing. It's a lisp that runs on the JVM. Apparently it's as fast as Java for a lot of things, despite being dynamically typed *. Java interop is about as convenient as I could imagine possible, though the native clojure libraries are already decent enough that you don't need to hit up Java for most things.

It also adds some "scripting language" sensibilities, like maps (-> Python dicts) and vectors (-> Python lists) to help reduce the likelihood of parenthetical paroxysm.

Oh right, concurrency. It uses a software transactional memory system which is pretty interesting in and of itself. Extra, extra: Read all about it.

*: I think you may need to use "type hinting" to get Java-like speed for a lot of tasks. This is made quite convenient in Clojure.

intuited
+1 for "parenthetical paroxysm" :-)
Cameron
A: 

Stackless Python as used by the EVE online developers might fit.

Stackless Python is an enhanced version of the Python programming language. It allows programmers to reap the benefits of thread-based programming without the performance and complexity problems associated with conventional threads. The microthreads that Stackless adds to Python are a cheap and lightweight convenience, which if used properly, can not only serve as a way to structure an application or framework, but by doing so improve program structure and facilitate more readable code.

Alex J. Roberts
+2  A: 

boo's syntax is Python-inspired. The programming language is a bit different, though: It's strongly typed with type-inference, and it's most imporant feature is probably the open compiler pipeline, i.e. the ability to create syntactic macros (in the LISP sense of the word "macro", not in the C sense of "preprocessor macro").

And, obviously, IronPyton is quite pythonic and about as good at threading as other .NET languages.

nikie
I didn't know `boo` had syntactic macros. Neat.
intuited
Neither did I. The documentation is a bit behind on that. I found out through Oren Eini's great book "DSLs in Boo" (www.manning.com/rahien). That's probably the best reference about Boo's syntactic macros features.
nikie
+3  A: 

Before anything else, what programming problem are you trying to solve? Has the GIL actually become a bottleneck yet? (If you're not sure, it probably hasn't.)

Without knowing this, you risk looking for a nail that fits your hammer, instead of the other way around.

If you really, really know that the GIL has become a bottleneck, and that you need to crunch numbers across multiple processors, then you want to consider:

  1. If you have known CPU-critical sections, compile them with C type declarations using Pyrex/Cython, if you can. This will firstly make them much more CPU-efficient than Python bytecode interpretation, and as a bonus, allow you to release the GIL around sections that don't need it. (Moral: turn your donkeys into racehorses before trying to parallelize them.)
  2. It should go without saying, but if you're using any CPU-intensive extension modules, make sure they're not already releasing the GIL for you.
  3. For almost everything else, use the built-in multiprocessing module. This gives you roughly the same API and advantages as threading, but provides you with true process-level concurrency: among other things, this allows you to easily run your CPU-intensive code on multiple machines in concert, which is critical if your problem actually gets big.
Piet Delport
I have begun using Cython and removing the GIL and that gets by for now.... But I want to make sure I have a contingency plan.
James
James: can you describe what the constraints of your problem actually are? It sounds like they're specific, and that can greatly affect the answer you're looking for.
Piet Delport
A: 

Take the hint. CPU intensive programs can also be made into multiple processes. Multiple processes and a pipeline to pass status around can often have outstanding performance.

Rather than fish around randomly for other languages, do this.

  1. Decompose the problem into a pipeline of steps that can be done concurrently.

    In the shell, the top-level script is this: a.py | b.py | c.py | d.py...

  2. Write each step as a very small Python loop that reads from sys.stdin and writes to sys.stdout. Interesting, this is the default for raw_input() and print() making things simple.

  3. Measure the performance.

You'll -- correctly -- spend all your time designing your algorithm. You'll spend little time coding or learning a new language. You'll trivially tie up every core on every CPU available to you. You'll spend no time on thread synchronization or other foolishness.

This kind of thing works very, very well for "CPU Intensive" applications.

S.Lott
I tried this out... The only problem was that I needed some local objects and didn't want to start pickling the objects to pass from one interpreter to the other.
James
@James: "I needed some local objects". Be careful of any design that requires shared write access to a common object. It's rarely necessary. Shared read-only access is one thing -- just use shelve. Shared write/mutate access is a problem waiting to happen. Keep working on your design to eliminate this shared writable access.
S.Lott
+1  A: 

You could just use python multiprocessing it mirrors the API of threading but runs separate processes. Might not be implemented for non-posix. For general CPU intensive problems you could always try Stackless Python (mentioned already) or Pyrex.

Makdaam
Added the links for you. :)
musicfreak