Préférer Python à C pour la programmation algorithmique

16

J'ai étudié un peu d'algorithmes et j'ai regardé des sites comme SPOJ.pl TopCoder etc. J'ai vu que les programmeurs préfèrent C ou C ++ généralement pour la plupart des concours de programmation algorithmique.

Maintenant, j'ai eu des problèmes ces derniers temps. Je connais à la fois un peu de C et Python et lorsque j'essaie d'écrire un code, je semble préférer Python à C pour la plupart des algorithmes. Chaque fois que je m'assois pour écrire un code dans CI, j'abandonne après environ 15 minutes parce que je le trouve trop lourd et j'ai tendance à passer en python. Passer des matrices Les pointeurs et ainsi de suite semblent être une perte de temps inutile que je pourrais réellement utiliser pour penser à l'algorithme lui-même.

Maintenant, je sais et j'ai entendu de nombreuses personnes que C est un langage très important et est le pain et le beurre de beaucoup de programmeurs.

Ce que je voulais savoir, c'était si cette approche avait des inconvénients / conséquences / inconvénients, etc.

Ce n'est pas un débat Python vs C; C'est une question sur la façon dont cette pratique spécifique de préférer python à C en raison de la facilité d'utilisation affectera moi-même ou tout autre programmeur / informaticien à long terme.


J'aimerais entendre des gens qui ont utilisé ces langages dans l'industrie / et / ou développer de grands logiciels / bibliothèques, etc.

ffledgling
la source
ce sujet ne sera pas complet sans lien vers cette discussion lukeplant.me.uk/blog/posts/…
permeakra
11
@permeakra: C'est juste une diatribe, déclarant essentiellement qu'apprendre Haskell et Python ne vous rend pas meilleur dans d'autres langues parce que ces autres langues sont nulles.
Robert Harvey
Ce n'est pas seulement une diatribe, car il contient une description de la façon dont Python et Haskell influencent l'esprit de leur utilisateur, et de nombreux commentaires d'autres peuples à ce sujet. Cependant, il n'utilise pas c comme langage de bas niveau, mais un peu plus de langage de haut niveau, mais l'idée est la même - on commence à apporter des idées d'une autre langue dans celle dans laquelle il travaille actuellement, ce qui rend le code non idiomatique . C'est peut-être une bonne chose, mais ...
permeakra
1
Voici mon opinion
Wayne Werner
Il aurait été intéressant de voir un peu de programmation non algorithmique , quelle que soit cette chose.
SK-logic

Réponses:

14

D'après mon expérience, lorsque les gens ont des difficultés excessives à coder les algorithmes en C, c'est souvent parce qu'ils couplent étroitement la gestion de leur structure de données avec leur algorithme au lieu de créer des abstractions appropriées. Par exemple, manipuler manuellement des pointeurs de liste liés partout au lieu de créer push()et de pop()fonctions. Ils sont trop habitués à ce que ces abstractions leur soient fournies.

Bien que ce problème soit beaucoup plus évident avec les abstractions de niveau inférieur, l'incapacité à reconnaître un couplage serré et à créer des abstractions appropriées est un problème à tous les niveaux. Pratiquer ces compétences en C jusqu'à ce que vous puissiez créer un algorithme qui semble propre et lisible sera transféré dans n'importe quelle langue que vous utilisez.

L'autre problème que je vois occasionnellement chez les programmeurs python est la difficulté à s'adapter aux performances à grande échelle. Certes, les performances ne sont généralement pas la principale préoccupation, mais la façon la plus pythonique d'implémenter un algorithme pour une structure de données relativement petite peut interrompre votre système lorsque vous travaillez avec des gigaoctets ou plus de données. Devenir un bon programmeur C vous aide à être plus conscient de ces types de problèmes dans n'importe quelle langue.

Pouvez-vous apprendre ces compétences dans d'autres langues? Bien sûr, mais C aide en le rendant beaucoup plus évident lorsque vous vous trompez.

Cela étant dit, j'utilise python pour la programmation algorithmique quand j'ai le choix, même si je suis tout aussi à l'aise en C. Python a des fonctionnalités de langage qui le rendent très agréable pour ce type de programmation, et les différences de performances sont généralement négligeables. Je ne peux pas expliquer pourquoi d'autres programmeurs qui connaissent les deux choisiraient C. J'imagine que beaucoup d'entre eux le font simplement pour se démarquer de la foule.

Karl Bielefeldt
la source
1
"Ils sont trop habitués à ce que ces abstractions leur soient fournies." Est-ce que cela suppose que j'ai appris le python avant C et que je ne peux donc pas m'adapter ou quelque chose dans ce sens?
ffledgling
10

Les chercheurs dont le principal intérêt n'est pas la programmation préfèrent les langages de niveau supérieur tels que Python, car ils peuvent coder une solution plus facilement dans ces langages que, disons, C. Python est particulièrement bien adapté à cela car il est plus orienté "prototypage", il est «piles incluses», et il s'intègre aux bibliothèques numériques telles que NumPy et SciPy.

Si un chercheur a besoin de meilleures performances, il remettra généralement l'algorithme qu'il a créé en Python à un ingénieur logiciel, qui trouvera des moyens de l'optimiser (jusqu'à et y compris, le recodage en C).

Robert Harvey
la source
Donc, fondamentalement, les chercheurs et les ingénieurs logiciels ont une relation concepteur-artisanat? Et qu'en est-il de l'utilisation des deux types de personnes dans l'industrie?
ffledgling
9
Je pense que le point à retenir est que le codage d'un algorithme en Python, puis l'écriture d'une implémentation plus raffinée en C, est un scénario parfaitement acceptable.
Robert Harvey
ou "recodage en Cython"?
endolith
10

Gardez à l'esprit SPOJ.pl, la compétition ACM et toutes les compétitions similaires se concentrent sur la production rapide de code de travail qui sera jeté juste après la compétition. TopCoder le fait, mais dans une moindre mesure (le code y est au moins correctement organisé au niveau de la conception OO).

Cependant, dans le monde réel de la programmation, presque tous les raccourcis que vous utiliseriez dans les compétitions de programmation algorithmique sont un anti-modèle. Ce n'est que si vous gardez cela à l'esprit que vous pouvez faire une sorte de comparaison. Prenons votre exemple: passer un tableau multidimensionnel entre différentes fonctions. Dans un environnement de concurrence, la meilleure approche serait de simplement déclarer le tableau global pour gagner du temps en calculant les détails de l'appel approprié (par exemple, dois-je passer la taille, ou peut-il être déterminé?). Dans la programmation réelle, je ferais exactement le contraire.

Donc, à votre question, y a-t-il des conséquences complexes à choisir Python plutôt que C pour les algorithmes, je dirais non. Si vous n'êtes intéressé que par l'algorithme, vous ferez la même chose en Python et C. L'implémenter dans un langage fonctionnel peut apporter quelques différences, mais l'algorithme est toujours le même.

Pratiquement la seule chose que vous avez gagnée en implémentant l'algorithme en C est plus de contrôle sur l'exécution et une garantie que vous n'utilisez que des abstractions de niveau inférieur. Ce n'est pas une petite chose, car en Python une grande partie de la complexité est cachée. Mais si le problème n'est pas anodin dans les abstractions de niveau supérieur, alors vous n'avez probablement perdu la vitesse d'exécution, et dans la plupart des cas, vous n'essayez pas vraiment de rendre le programme aussi rapide que possible, vous apprenez simplement .

Comme déjà suggéré, vous pouvez toujours échanger une implémentation Python avec une implémentation C si Python s'avère trop lent. Mais cela se produira probablement 2-3 fois dans un projet énorme, donc commencer en C peut être une perte de temps, à moins que ce soit votre langue de choix (et vous avez indiqué que ce n'est pas le cas).

K.Steff
la source
1
Si l'on écrivait une vraie application intensive en mathématiques, on choisirait presque certainement le C ou le C ++ (il n'y a pas de «C / C ++») en raison de l'énorme augmentation des performances par rapport à tout langage interprété. J'ai regardé Topcoder il y a quelques années, et je me souviens avoir vu beaucoup de C ++ qui fuyaient de la mémoire sans motif, car les concours ne se souciaient pas de détails mineurs comme les fuites. Je n'étais pas impressionné.
Jim In Texas
Précisément mon point. C'est une question de priorités: les topcoders ne se soucient pas des fuites de mémoire, puisque le noyau va de toute façon les nettoyer; ils ne se soucient pas des mauvaises pratiques ni des anti-modèles, s'ils gagnent du temps.
K.Steff
2
Votre dernier paragraphe incarne la règle d'or: "faites-le fonctionner, puis faites-le vite".
Carson63000
9

En tant que membre de longue date de TopCoder et utilisateur occasionnel de SPOJ, je peux vous dire qu'une raison majeure de préférer le C / C ++ aux autres langages dans les compétitions est sa vitesse brute. Lorsque l'exécution de votre programme est chronométrée, il y a une énorme pression pour choisir le langage "le plus rapide" que vous pouvez obtenir, car cela vous donne plus de mou en termes de codage de votre algorithme. Ma progression dans TC est passée de Java à C # à C ++.

Cependant, cette situation est plus courante dans les compétitions que dans le développement quotidien: bien que l'écriture d'un code optimal soit universellement importante, l'importance relative de terminer votre code dès que vous le pouvez et de le rendre aussi maintenable que possible l'emporte généralement sur la sauvegarde de quelques-uns cent cycles CPU. Si vous préférez coder quelque chose en Python, c'est très souvent une solution préférée.

De plus, Python offre des capacités de haut niveau qui ne sont pas disponibles en C ++. Les construire est souvent très coûteux et parfois même impossible (par exemple, envisagez de construire une réflexion ou un code auto-modifiable en C ++). Dans des cas comme celui-ci, s'appuyer sur un langage de niveau supérieur peut également s'avérer être une solution optimale.

dasblinkenlight
la source
Puisque vous êtes un utilisateur de TC et SPOJ. Le compromis entre le temps et la simplicité est-il très important si nous utilisons python pour le code? C'est-à-dire qu'il est possible de faire des soumissions réussies en utilisant python si le même algorithme peut être soumis avec succès en utilisant C? (Oui, je sais que cela variera / pourrait varier considérablement d'une question à l'autre, mais y aura-t-il un désavantage dans la plupart des cas ou juste pour certains?)
ffledgling
@Ayos Je ne peux pas parler pour Python parce que je ne l'ai jamais utilisé dans le contexte de TC ou SPOJ, mais l'avantage de C ++ sur C # et Java n'est qu'occasionnellement important, et même alors, il n'est pas trop significatif. Je ne me souviens que d'un cas où un port simple d'un algorithme qui a été codé en C ++ vers C # a échoué avec un délai d'attente, mais c'était dans une salle de pratique. La plupart du temps, la découverte de l'algorithme correct est la seule chose qui fait la différence entre les soumissions réussies et échouées.
dasblinkenlight
1
Notez que les langages interprétés comme Python, Ruby et Perl s'exécutent plusieurs fois plus lentement que les langages de haut niveau compilés comme Java et C # (qui sont eux-mêmes lents par rapport à C). En fin de compte, cela n'a pas vraiment d'importance, sauf si vous prévoyez de travailler avec des ensembles de données exceptionnellement volumineux ou si vous avez besoin d'une vitesse en temps réel.
KChaloux
5

Chaque fois que je m'assois pour écrire un code dans CI, j'abandonne après environ 15 minutes parce que je le trouve trop lourd et j'ai tendance à passer en python.

Ce gain de productivité est la raison courante pour laquelle les emplois C et C ++ ont considérablement diminué.

C'est une question sur la façon dont cette pratique spécifique de préférer python à C en raison de la facilité d'utilisation m'affectera, moi ou tout autre programmeur / informaticien à long terme.

Il y a deux parties principales à cela. Le premier est la programmation algortihmique. Peu importe la langue que vous utilisez pour exprimer l'algorithme. Travailler avec l'algorithme lui-même et adapter les bons aux bons problèmes sont les éléments clés, il n'y a donc pas de vrai problème.

La deuxième partie concerne les gains de productivité. Utiliser des choses qui vous rendent plus productif au fil du temps est une bonne habitude et quelque chose qui ne fera que vous profiter au cours de votre carrière. Être capable d'exprimer les algorithmes dans différentes langues est très utile, mais cette utilité repose davantage sur les idiomes que les langues utilisent pas nécessairement sur ce que sont ces langues.

Bref, ne vous en faites pas . Ce que vous utilisez pour exprimer l'algorithme est beaucoup moins important que de pouvoir l'exprimer du tout.

Telastyn
la source
3
"Les emplois C et C ++ ont considérablement diminué". Hein? Cela semble pris à l'improviste, car je vois la tendance inverse. -1 jusqu'à ce que vous puissiez indiquer une source pour cette déclaration.
3

Les avantages d'utiliser des langages de niveau supérieur comme Python ou Ruby sont que (1) leur syntaxe est très proche du pseudocode et (2) leurs bibliothèques standard fournissent des structures de données utiles prêtes à l'emploi (le concept de batteries inclus mentionné par @Robert). Il est donc parfaitement bien de préférer les utiliser. Utilisez tout ce qui maximise votre productivité, au lieu de choisir une langue simplement parce qu'elle est courante ou "cool".

sakisk
la source
Êtes-vous un hipster ou quelque chose? Voici votre PBR. Moi? Je préfère être cool.
Thomas Eding
2

Ce que vous manquerez lors de la programmation dans des langages de niveau "supérieur" que C / C ++, c'est le fonctionnement des ordinateurs. Vous ne pourrez pas développer des choses comme les systèmes embarqués, les systèmes d'exploitation et les pilotes matériels. La connaissance de C aide également lors de l'apprentissage de l'assembleur.

De plus, la grande majorité de tous les systèmes essentiels à la mission sont encore développés en C, donc vous ne pourrez peut-être pas travailler dans plusieurs branches de logiciels (aérospatiale / automobile / med-tech, etc.) sans le savoir.


la source
La question portait explicitement sur les algorithmes, pas sur les aspects proches du métal.
Konrad Rudolph
@KonradRudolph Bien, mais l'écriture de pilotes matériels est le plus souvent très étroitement liée aux algorithmes. Par exemple, lors de l'écriture d'un pilote pour un convertisseur analogique-numérique, vous devrez développer des filtres numériques et peut-être aussi une sorte de file d'attente ou de système de priorité. Et puis une API au dessus de votre pilote. C'est très similaire à l'écriture d'un "objet" ou d'un "type de données abstrait".
@Lundin Merci d'avoir mentionné les inconvénients du scénario réel.
ffledgling
1

Si une question continue sur la `` notation Big O '' et que vous essayez de la mesurer, il peut être plus difficile de le faire en Python à moins d'en savoir beaucoup plus sur la façon dont python implémente les choses, par exemple une liste Python n'est pas une liste liée ; Le type Pythons est TimSort; Les ordures en python s'accumulent à certains moments ...

Je trouve toujours plus facile de connecter un programme C à ce qui est susceptible de se produire sur un processeur, mais même ici, il y a mise en cache du processeur; découpage temporel du système d'exploitation; Optimisations du compilateur, etc. qui peuvent affecter mon intuition.

Je trouve qu'il est plus rapide d'écrire et de déboguer du code Python, donc, si on me donnait le choix, j'écrirais d'abord en Python en me concentrant sur l'obtention de quelque chose qui fonctionnait. Avec ce programme Python fonctionnel, vous pouvez souvent le placer dans un système plus grand et découvrir non seulement qu'il a fonctionné, mais aussi s'il était assez rapide ou dans quel aspect était-il lent. L'obtention de données de performances réelles aide ensuite lorsque vous optimisez la vitesse et vous permet de tester la version Python par rapport à toute réécriture ultérieure en Python ou C ou autre.

Par conséquent, les inconvénients de l'utilisation de Python uniquement sont qu'il peut être difficile de profiter des avantages des algorithmes écrits en attendant une compilation de type C sur le modèle de processeur. Les inconvénients de l'utilisation de C sont comme vous l'avez dit: c'est un cochon pour écrire et déboguer et vous finissez par devoir écrire vos propres bibliothèques trop souvent.

Je pense qu'il serait préférable de les utiliser à la fois (et dans d'autres langues), jusqu'à ce que vous compreniez leurs compromis. J'étais moi-même un bon codeur C, mais maintenant j'écris très peu de code C original, même si je dois encore lire (et parfois déboguer) du code C dans mon travail. Bien que je préfère Python, je connais et utilise toujours Perl et Awk (et sed et grep et sort et Tcl et C et ...).

Paddy3118
la source
Je ne suis pas d'accord avec le premier paragraphe. Python met fortement l'accent sur les structures de données et documente clairement comment les structures de données prédéfinies sont mises en œuvre. Bien sûr, la collecte des ordures faussera les temps d'exécution, mais elle faussera rarement l'ordre big-O.
Konrad Rudolph
1

Je vous conseillerais de regarder Scala ou Clojure (mais utilisez des annotations de type). Dans certains cas, ils peuvent être aussi rapides que C, dans d'autres cas, ils sont encore beaucoup plus rapides que Ruby / Python, tout en ayant une notation très concise et claire contrairement à C ( IMHO ). Considérez ce code vs C:

for (i <- 1 to 100; j <- 2 until 100;
     k <- 1 to 2; if i != j) {
     //...
}

En outre , ils ont l' arsenal de programmation de fonction similaire à Ruby / Python map, filter, reduceetc qui est pas aussi rapide que itérer ou récursion appel de la queue, mais il est encore beaucoup plus rapide que les langages de script entièrement dynamiques.

defhlt
la source
1

J'aimerais entendre des gens qui ont utilisé ces langages dans l'industrie / et / ou développer de grands logiciels / bibliothèques, etc.

J'ai travaillé sur une petite partie d'une grande bibliothèque C ++ pendant quelques années, et j'ai écrit à la fois mon baccalauréat et ma thèse dans le contexte de cette bibliothèque. La bibliothèque, soit dit en passant, est une bibliothèque d'algorithmes bioinformatiques et de structures de données.

La bibliothèque est construite en C ++ car C ++ est presque parfait pour les exigences spécifiques de cette bibliothèque et pour les bibliothèques d'algorithmes en général. Si je devais développer une autre bibliothèque d'algorithmes et que le choix du langage était le mien, je choisirais presque certainement C ++ à nouveau.

La raison n'est pas seulement la performance, mais aussi le système de type solide qui, tout d'abord, vous donne plus de sécurité et, en second lieu, vous permet de laisser vos types documenter l'algorithme utilisé. D'après mon expérience, cela peut améliorer considérablement la lisibilité et la maintenabilité.

Cela dit, pour les doodles et les casse-tête algorithmiques simples, j'utilise presque toujours Python (principalement parce que oui, il se lit presque comme un pseudo-code), sauf si je veux spécifiquement essayer de formuler au mieux un problème en C ++. Jusqu'à présent, je n'ai pas résolu de nombreux problèmes SPOJ ou TopCoder, donc je ne sais pas si les performances sont vraiment si critiques que l'utilisation d'un langage rapide est cruciale.

Mais normalement, ce qui compte, c'est d'obtenir l' algorithme pour passer. Dans ces cas, Python fonctionne très bien. Par exemple, pour les problèmes Project Euler (qui ne sont pas chronométrés, seule la bonne solution compte), Python est parfaitement adapté.

Konrad Rudolph
la source