2010-10-12 5 views
3

Maintenant j'écris principalement en python, mais je cherche un langage plus convivial (pas JAVA, C#, C ou C++).Langue multithread "Pythonic" (Concurrent)

Les threads de Python sont bons quand ils sont liés à l'E/S, mais cela arrive quand je fais quelque chose de CPU.

Des idées?

Merci, James

+0

Je n'ai jamais vraiment compris où est la ligne "subjective", mais ce site a pour règle de déplacer ces sujets vers http://programmers.stackexchange.com/ ou de cocher la case "Community Wiki" . Je pense que cette question est qualifiée de sujet; vous pouvez "CW-ify" en éditant la question et en cochant la case. – intuited

+1

Je n'ai jamais vu clairement la ligne "subjective" non plus, mais en faisant de cette question un CW avant que la police proche trouve que c'est probablement une bonne idée. – Niki

+0

Pourquoi avez-vous décidé que les threads (et non les processus) sont la meilleure façon de résoudre vos besoins de simultanéité? –

Répondre

1

Python est loin en ce qui concerne les tâches intensives CPU parce que Python n'est pas une langue très efficace . Beaucoup de langages "dynamiques" ont ce problème, puisque le compilateur est limité dans ce qu'il peut supposer au sujet du programme à la compilation. Les appels de méthode, par exemple, peuvent devoir être recherchés à chaque fois au cas où quelqu'un aurait remplacé la méthode sur l'objet entre chaque invocation.

Je vous recommande de jeter un oeil à Erlang, même si ce n'est probablement pas "Pythonic" dans votre sens du mot. :-)

+0

+1 pour Erlang. La syntaxe et les variables bind-once peuvent être un peu surprenantes au départ. –

+0

Pythonic signifie que c'est un langage amusant à écrire. Est-ce qu'Erlang est compilé? De même, comment les processus se comparent-ils aux threads? – James

+0

@Mark Pourquoi ne pas utiliser Erlang? – James

1

pour surmonter GIL, vous pouvez essayer d'interpréter le langage python avec Jython au lieu de CPython

+0

Merci, mais j'essaie de m'éloigner de Java. Vous cherchez un nouveau langage maintenant .... (bien que PyPy semble prometteur) – James

+4

@ user386129 bien, jython est java dans la même mesure que cpython est c :) – mykhal

+0

Aussi dans le test de jython (un petit code de test) je vois que c'est plus lent que cPython – James

7

Clojure est très amusant, si vous êtes dans ce genre de chose. C'est un lisp qui fonctionne sur la JVM. Apparemment, il est aussi rapide que Java pour beaucoup de choses, en dépit d'être dynamiquement typé *. Java interop est à peu près aussi pratique que je pourrais l'imaginer, bien que les librairies de clojure natives soient déjà assez décentes pour que vous n'ayez pas besoin de lancer Java pour la plupart des choses. Il ajoute également quelques sensibilités de "langage de script", comme les cartes (-> Python dicts) et les vecteurs (-> listes Python) pour aider à réduire la probabilité de paroxysme entre parenthèses.

Ah oui, la simultanéité. Il utilise un système de mémoire transactionnel logiciel qui est assez intéressant en soi. Extra, extra: Read all about it. *: Je pense que vous devrez peut-être utiliser "type hinting" pour obtenir une vitesse semblable à Java pour beaucoup de tâches. C'est très pratique à Clojure.

+0

+1 pour "parenthetical paroxysm" :-) – Cameron

2

Stackless Python comme utilisé par les développeurs EVE online pourrait s'adapter.

Stackless Python est une amélioration version de la programmation Python langage. Il permet aux programmeurs de profiter des avantages de la programmation à base de threads sans les performances et les problèmes de complexité associés avec les threads conventionnels. Les microfiletages que Stackless ajoute à Python sont une commodité pas cher et léger, qui si elles sont utilisées correctement, ne peut pas servir uniquement comme un moyen de la structure une application ou cadre, mais en faisant améliorer si la structure du programme et faciliter plus code lisible .

3

La syntaxe de boo est inspirée de Python. Le langage de programmation est un peu différent, cependant: Il est fortement typé avec l'inférence de type, et sa fonction la plus importante est probablement le pipeline de compilateur ouvert, ie la capacité de créer des macros syntaxiques (au sens LISP du mot "macro", pas dans le sens C de "macro de préprocesseur").Et, de toute évidence, IronPyton est assez pythonique et à peu près aussi bien au threading que d'autres langages .NET.

+0

Je ne savais pas que 'boo' avait des macros syntaxiques. Soigné. – intuited

+0

Moi non plus. La documentation est un peu en retard sur ce point.J'ai découvert grâce au grand livre d'Oren Eini "DSLs in Boo" (www.manning.com/rahien). C'est probablement la meilleure référence sur les fonctionnalités des macros syntaxiques de Boo. – Niki

4

Avant toute chose, quel problème de programmation essayez-vous de résoudre? Le GIL est-il devenu un goulot d'étranglement? (Si vous n'êtes pas sûr, ce n'est probablement pas le cas.)

Sans le savoir, vous risquez de devoir chercher un clou adapté à votre marteau plutôt que l'inverse.

Si vous avez vraiment, vraiment savoir que le GIL est devenu un goulot d'étranglement, et que vous avez besoin de croquer des nombres sur plusieurs processeurs, alors que vous voulez examiner:

  1. Si vous avez connu des sections critiques CPU, compilez-les avec des déclarations de type C en utilisant Pyrex/Cython, si vous le pouvez. Cela les rendra d'abord beaucoup plus efficaces que l'interprétation Python bytecode, et en prime, vous permettra de libérer le GIL autour des sections qui n'en ont pas besoin. (Morale: transformez vos ânes en chevaux de course avant d'essayer de les paralléliser.)
  2. Cela devrait aller de soi, mais si vous utilisez des modules d'extension gourmands en ressources, assurez-vous qu'ils ne libèrent pas déjà le GIL pour vous. Pour presque tout le reste, utilisez le module multiprocessing intégré. Cela vous donne à peu près la même API et les mêmes avantages que threading, mais vous offre vrai niveau de concurrence au niveau du processus: entre autres choses, cela vous permet d'exécuter facilement votre code CPU sur plusieurs machines de concert, ce qui est essentiel si votre le problème devient gros.
+0

J'ai commencé à utiliser Cython et à supprimer le GIL et ça se passe pour l'instant ... Mais je veux m'assurer d'avoir un plan d'urgence. – James

+2

James: pouvez-vous décrire les contraintes de votre problème? Cela semble être spécifique, et cela peut grandement affecter la réponse que vous cherchez. –

1

Prenez l'indice. Les programmes intensifs de CPU peuvent également être transformés en plusieurs processus. Plusieurs processus et un pipeline pour passer le statut peuvent souvent avoir des performances exceptionnelles. Plutôt que de pêcher au hasard dans d'autres langues, faites-le.

  1. Décomposer le problème en un pipeline d'étapes pouvant être effectuées simultanément.

    Dans le shell, le script de haut niveau est la suivante: a.py | b.py | c.py | d.py ...

  2. Ecrire chaque étape comme une boucle Python très petit qui lit et écrit sys.stdin à sys.stdout. Intéressant, ceci est la valeur par défaut pour raw_input() et print() rendant les choses simples.

  3. Mesurer la performance.

Vous allez - correctement - passer tout votre temps à concevoir votre algorithme. Vous passerez peu de temps à coder ou à apprendre une nouvelle langue. Vous aurez trivialement attacher chaque noyau sur chaque processeur à votre disposition. Vous ne passerez pas de temps sur la synchronisation des threads ou autres folies.

Ce genre de chose fonctionne très, très bien pour les applications "CPU Intensif".

+0

J'ai essayé cela ... Le seul problème était que j'avais besoin d'objets locaux et que je ne voulais pas commencer à décaper les objets pour passer d'un interpréteur à l'autre. – James

+2

@James: "J'avais besoin d'objets locaux". Faites attention à toute conception qui nécessite un accès en écriture partagé à un objet commun. C'est rarement nécessaire. L'accès partagé en lecture seule est une chose - utilisez simplement shelve. L'accès partagé écriture/mutation est un problème qui risque de se produire. Continuez à travailler sur votre conception pour éliminer cet accès accessible en écriture partagé. –

1

Vous pouvez simplement utiliser python multiprocessing il reflète l'API de threading mais exécute des processus séparés. Ne peut pas être implémenté pour un non-posix.Pour les problèmes généraux de CPU, vous pouvez toujours essayer Stackless Python (déjà mentionné) ou Pyrex.

+0

Ajout des liens pour vous. :) –