Preferencia de Python sobre C para la programación algorítmica

16

He estado estudiando un poco de algoritmos y he estado buscando sitios como SPOJ.pl TopCoder, etc. He visto que los programadores prefieren C o C ++ generalmente para la mayoría de los concursos de programación algorítmica.

Ahora he tenido algunos problemas últimamente. Sé un poco de C y Python y cuando trato de escribir un código, prefiero Python sobre C para la mayoría de los algoritmos. Cada vez que me siento a escribir un código en CI me doy por vencido después de unos 15 minutos porque me parece demasiado engorroso y tiendo a pasar a Python. Pasar matrices Los punteros, etc., parecen ser una pérdida de tiempo inútil que podría utilizar para pensar en el algoritmo en sí.

Ahora sé y he escuchado de mucha gente que el C es un lenguaje muy importante y es el pan de cada día de muchos programadores.

Lo que quería saber era si este enfoque mío tiene algún inconveniente / consecuencias / desventajas, etc.

Este no es un debate Python vs C; Esta es una pregunta sobre cómo esta práctica específica de preferir Python sobre C debido a la facilidad de uso me afectará a mí oa cualquier otro programador / informático a largo plazo.


Me encantaría saber de personas que han usado estos idiomas en la industria / y / o para desarrollar grandes bibliotecas / software, etc.

incipiente
fuente
este tema no estará completo sin un enlace a esta discusión lukeplant.me.uk/blog/posts/…
permeakra
11
@permeakra: Eso es solo una queja, básicamente afirmando que aprender Haskell y Python no te hace mejor en otros idiomas porque esos otros idiomas apestan.
Robert Harvey
No es solo una queja, ya que contiene una descripción de cómo Python y Haskell influyen en la mente de sus usuarios, y muchos comentarios de otras personas sobre ese tema. Sin embargo, no usa c como lenguaje de bajo nivel en comparación, pero es un poco más lenguaje de alto nivel, pero la idea es la misma: uno comienza a traer ideas de otro lenguaje al que está trabajando actualmente, haciendo que el código no sea idiomático . Puede ser algo bueno, pero ...
permeakra
1
Esta es mi opinión: plus.google.com/101996847784434186165/posts/7941QuL69yP
Wayne Werner
Hubiera sido interesante ver un poco de programación no algorítmica , sea lo que sea.
SK-logic

Respuestas:

14

En mi experiencia, cuando las personas tienen dificultades excesivas para codificar algoritmos en C, a menudo se debe a que están estrechamente acoplando su gestión de estructura de datos con su algoritmo en lugar de crear abstracciones apropiadas. Por ejemplo, manipulando manualmente punteros de lista vinculados en todas partes en lugar de hacer push()y pop()funciones. Están demasiado acostumbrados a recibir esas abstracciones.

Si bien este problema es mucho más evidente con las abstracciones de nivel inferior, no reconocer el acoplamiento estrecho y crear abstracciones apropiadas es un problema en cualquier nivel. Practicar estas habilidades en C hasta que pueda hacer un algoritmo que se vea limpio y legible se transferirá a cualquier lenguaje que use.

El otro problema que veo ocasionalmente entre los programadores de Python es la dificultad para adaptarse al rendimiento a escala. Por supuesto, el rendimiento no suele ser la principal preocupación, pero la forma más pitónica de implementar un algoritmo para una estructura de datos relativamente pequeña puede detener su sistema cuando trabaje con gigabytes o más de datos. Convertirse en un buen programador de C le ayuda a ser más consciente de ese tipo de problemas en cualquier idioma.

¿Puedes aprender esas habilidades en otros idiomas? Claro, pero C ayuda haciéndolo mucho más obvio cuando te equivocas.

Dicho esto, uso Python para la programación algorítmica cuando tengo una opción, a pesar de que estoy tan cómodo en C. Python tiene características de lenguaje que lo hacen muy bueno para ese tipo de programación, y las diferencias de rendimiento generalmente son insignificantes. No puedo hablar de por qué otros programadores que saben que ambos elegirían C. Me imagino que muchos de ellos lo hacen simplemente para diferenciarse de la multitud.

Karl Bielefeldt
fuente
1
"Están demasiado acostumbrados a recibir esas abstracciones". ¿Asume esto que aprendí Python antes de C y, por lo tanto, no puedo adaptarme o algo por el estilo?
incipiente
10

Los investigadores cuyo interés principal no es la programación prefieren lenguajes de nivel superior como Python, porque pueden codificar una solución más fácilmente en dichos lenguajes que, por ejemplo, C. Python es particularmente adecuado para esto porque está más orientado a la "creación de prototipos". "baterías incluidas", y se integra con bibliotecas numéricas como NumPy y SciPy.

Si un investigador necesita un mejor rendimiento, generalmente entregará el algoritmo que creó en Python a un ingeniero de software, que encontrará formas de optimizarlo (hasta, incluida la recodificación en C).

Robert Harvey
fuente
Entonces, ¿básicamente los investigadores y los ingenieros de software tienen una relación de diseñador Crafts-man? ¿Y qué hay de la utilización de ambos tipos de personas en la industria?
incipiente
9
Creo que la conclusión es que codificar un algoritmo en Python, y luego escribir una implementación más refinada en C, es un escenario perfectamente aceptable.
Robert Harvey
o "recodificación en Cython"?
endolito
10

Tenga en cuenta SPOJ.pl, la competencia ACM y todas las competiciones similares se centran en producir un código de trabajo rápido que se desechará inmediatamente después de la competencia. TopCoder hace esto, pero en menor medida (el código está al menos correctamente organizado en el nivel de diseño OO).

Sin embargo, en el mundo real de la programación, casi todos los atajos que tomarías en las competencias de programación algorítmica son un antipatrón. Solo si tiene esto en cuenta, puede hacer algún tipo de comparación. Tomemos su ejemplo: pasar una matriz multidimensional entre diferentes funciones. En un entorno de competencia, el mejor enfoque sería simplemente declarar la matriz global para ahorrar tiempo calculando los detalles adecuados de la llamada (por ejemplo, ¿debo pasar el tamaño o puedo determinarlo?). En la programación de la vida real, haría exactamente lo contrario.

Entonces, a su pregunta, ¿hay alguna consecuencia compleja de elegir Python sobre C para algoritmos? Yo diría que no. Si solo está interesado en el algoritmo, hará lo mismo en Python y C. Implementarlo en un lenguaje funcional puede presentar algunas diferencias, pero el algoritmo sigue siendo el mismo.

Prácticamente lo único que ha ganado al implementar el algoritmo en C es un mayor control sobre la ejecución y una garantía de que está utilizando solo abstracciones de nivel inferior. Esto no es algo pequeño, ya que en Python gran parte de la complejidad está oculta. Pero si el problema no es trivial en las abstracciones de nivel superior, entonces posiblemente solo haya perdido la velocidad de ejecución, y en la mayoría de los casos, en realidad no está tratando de hacer que el programa sea lo más rápido posible, simplemente está aprendiendo .

Como ya se sugirió, siempre puede intercambiar una implementación de Python con una implementación de C si Python resulta ser demasiado lento. Pero esto sucederá probablemente 2-3 veces en un gran proyecto, por lo que comenzar en C puede ser una pérdida de tiempo, a menos que sea su lenguaje de elección (y haya indicado que no lo es).

K.Steff
fuente
1
Si uno escribiera una aplicación matemática real, seguramente elegiría C o C ++ (no existe tal cosa como 'C / C ++') debido al enorme aumento del rendimiento sobre cualquier lenguaje interpretado. Miré a Topcoder hace un par de años, y recuerdo haber visto mucho C ++ que perdía memoria sin motivo, ya que a los concursos no les importaban detalles menores como las filtraciones. No me impresionó.
Jim In Texas
Precisamente mi punto. Es una cuestión de prioridades: los topcoders no se preocupan por las pérdidas de memoria, ya que el núcleo se limpiará después de ellos de todos modos; no les importan las malas prácticas ni los antipatrones, si ahorran tiempo.
K.Steff
2
Su último párrafo encarna la regla de oro: "haz que funcione, luego hazlo rápido".
Carson63000
9

Como miembro veterano de TopCoder y usuario ocasional de SPOJ, puedo decirle que una razón importante para preferir C / C ++ a otros idiomas en las competiciones es su velocidad bruta. Cuando el tiempo de ejecución de su programa es cronometrado, existe una enorme presión para elegir el lenguaje "más rápido" que pueda obtener, porque le da más holgura en términos de codificación de su algoritmo. Mi progresión en TC pasó de Java a C # a C ++.

Sin embargo, esta situación es más común en las competiciones que en el desarrollo del día a día: aunque escribir código óptimo es universalmente importante, la importancia relativa de terminar su código lo antes posible y hacerlo lo más fácil de mantener generalmente supera el ahorro de algunos Cien ciclos de CPU. Si se siente más cómodo codificando algo en Python, a menudo es una solución preferida.

Además, Python ofrece capacidades de alto nivel que no están disponibles en C ++. Construirlos a menudo es muy costoso y, a veces, incluso imposible (por ejemplo, considere construir un código de reflexión o auto modificable en C ++). En casos como ese, confiar en un lenguaje de nivel superior también puede ser una solución óptima.

dasblinkenlight
fuente
Como eres usuario de TC y SPOJ. ¿Es muy grande el intercambio entre tiempo y simplicidad si usamos python para el código? Es decir, ¿es posible realizar presentaciones exitosas usando python si el mismo algoritmo puede enviarse exitosamente usando C? (Sí, sé que variará / podría variar mucho de una pregunta a otra, pero ¿habrá una desventaja en la mayoría de los casos o solo en algunos?)
incipiente
@Ayos No puedo hablar por Python porque nunca lo usé en el contexto de TC o SPOJ, pero la ventaja de C ++ sobre C # y Java es solo ocasionalmente importante, e incluso entonces no es demasiado significativa. Solo recuerdo un caso cuando un puerto directo de un algoritmo que ha sido codificado en C ++ a C # ha fallado con un tiempo de espera, pero estaba en una sala de práctica. La mayoría de las veces, descubrir el algoritmo correcto es lo único que marca la diferencia entre envíos exitosos y fallidos.
dasblinkenlight
1
Tenga en cuenta que los lenguajes interpretados como Python, Ruby y Perl se ejecutan varias veces más lento que los lenguajes de alto nivel compilados como Java y C # (que en sí mismos son lentos en comparación con C). Sin embargo, en última instancia, no importa a menos que planee trabajar con conjuntos de datos excepcionalmente grandes o necesite velocidad en tiempo real.
KChaloux
5

Cada vez que me siento a escribir un código en CI me doy por vencido después de unos 15 minutos porque me parece demasiado engorroso y tiendo a pasar a Python.

Esta ganancia de productividad es la razón común por la cual los trabajos en C y C ++ han disminuido sustancialmente.

Esta es una pregunta sobre cómo esta práctica específica de preferir Python sobre C debido a la facilidad de uso me afectará a mí oa cualquier otro programador / informático a largo plazo.

Hay dos partes centrales para esto. El primero es la programación algortímica. Realmente no importa qué lenguaje uses para expresar el algoritmo. Trabajar con el algoritmo en sí mismo y ajustar los problemas correctos en los problemas correctos son las partes clave, por lo que no hay un problema real allí.

La segunda parte son las ganancias de productividad. Usar cosas que lo hacen más productivo con el tiempo es un buen hábito, y algo que no hará más que beneficiarlo durante su carrera. Ser capaz de expresar los algoritmos en diferentes idiomas es muy útil, pero esa utilidad se basa más en qué modismos usan los idiomas, no necesariamente cuáles son esos idiomas.

En resumen, no te preocupes por eso . Lo que usa para expresar el algoritmo es mucho menos importante que poder expresarlo.

Telastyn
fuente
3
"Los trabajos C y C ++ han disminuido sustancialmente". ¿Eh? Esto parece sacado de la nada, ya que veo la tendencia opuesta. -1 hasta que pueda indicar una fuente para esa declaración.
3

Las ventajas de usar lenguajes de nivel superior como Python o Ruby son que (1) su sintaxis está muy cerca del pseudocódigo y (2) sus bibliotecas estándar proporcionan estructuras de datos útiles listas para usar (el concepto de baterías incluidas que @Robert mencionó). Así que está perfectamente bien preferir usarlos. Use lo que maximice su productividad, en lugar de elegir un idioma solo porque es convencional o "genial".

sakisk
fuente
¿Eres un hipster o algo así? Aquí está tu PBR. ¿Yo? Prefiero ser genial.
Thomas Eding
2

Lo que se perderá al programar en lenguajes de nivel "superior" que C / C ++ es aprender cómo funcionan las computadoras. No podrá desarrollar cosas como sistemas integrados, sistemas operativos y controladores de hardware. Saber C también ayuda cuando se aprende ensamblador.

Además, la gran mayoría de todos los sistemas de misión crítica todavía se desarrollan en C, por lo que es posible que no pueda trabajar en varias ramas de software (aeroespacial / automotriz / med-tech, etc.) sin saberlo.


fuente
La pregunta era explícitamente sobre algoritmos, no sobre aspectos cercanos al metal.
Konrad Rudolph
@KonradRudolph Bien, pero escribir controladores de hardware suele estar muy relacionado con algoritmos. Por ejemplo, al escribir un controlador para un convertidor analógico a digital, tendrá que desarrollar filtros digitales y quizás también algún tipo de cola o sistema de prioridad. Y luego una API en la parte superior de su controlador. Es muy similar a escribir un "objeto" o "tipo de datos abstractos".
@Lundin Gracias por mencionar las desventajas en el escenario del mundo real.
incipiente
1

Si alguna vez se produce una pregunta sobre 'Big O notation' e intenta medirlo, entonces puede ser más difícil hacerlo en Python a menos que sepa mucho más sobre cómo Python implementa las cosas, por ejemplo, una lista de Python no es una lista vinculada ; Pythons sort es TimSort; La basura de Python se acumula en ciertos momentos ...

Siempre me resulta más fácil conectar un programa en C a lo que probablemente esté sucediendo en un procesador, pero incluso aquí, hay almacenamiento en caché del procesador; corte de tiempo del sistema operativo; Optimizaciones del compilador, etc. que pueden afectar mi intuición.

Me resulta más rápido escribir y depurar el código de Python, por lo que, cuando tengo la opción, escribiría primero en Python concentrándome en obtener algo que funcionó. Con este programa de Python en funcionamiento, a menudo puede ubicarlo en un sistema más grande y descubrir no solo que funcionó, sino también si fue lo suficientemente rápido o en qué aspecto fue lento. Obtener algunos datos de rendimiento real ayuda cuando optimiza la velocidad y le permite probar la versión de Python contra cualquier reescritura posterior en Python o C o lo que sea.

Entonces, los inconvenientes de usar solo Python es que puede ser difícil cosechar los beneficios de los algoritmos que se escribieron esperando una compilación tipo C para el modelo de procesador. Las desventajas de usar solo C son las que usted ha indicado: es un cerdo para escribir y depurar y termina teniendo que escribir sus propias bibliotecas con demasiada frecuencia.

Creo que sería mejor usar ambos (y otros idiomas), hasta que tenga una idea de sus compensaciones. Yo mismo era un buen codificador C pero ahora escribo muy poco código C original, aunque todavía tengo que leer (y a veces depurar) el código C en mi trabajo. Aunque prefiero Python, sé y sigo usando Perl y Awk (y sed y grep y sort y Tcl y C y ...).

Paddy3118
fuente
No estoy de acuerdo con el primer párrafo. Python tiene un fuerte énfasis en las estructuras de datos y documenta claramente cómo se implementan las estructuras de datos predefinidas. Por supuesto, la recolección de basura sesgará los tiempos de ejecución, pero rara vez sesgará el orden big-O.
Konrad Rudolph el
1

Te aconsejaría que mires Scala o Clojure (pero usa anotaciones de tipo). En algunos casos pueden ser tan rápidos como C, en otros casos aún son mucho más rápidos que Ruby / Python, mientras que tienen una notación muy consistente y clara a diferencia de C (en mi humilde opinión ). Considere este código vs C:

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

También tienen el arsenal de programación función similar a Ruby / Python map, filter, reduceetc, que no es tan rápido como la iteración o recursividad llamada de cola, sin embargo, es todavía mucho más rápido que los lenguajes de script totalmente dinámicos.

defhlt
fuente
1

Me encantaría saber de personas que han usado estos idiomas en la industria / y / o para desarrollar grandes bibliotecas / software, etc.

He trabajado en una pequeña parte de una gran biblioteca de C ++ durante algunos años, y he escrito mi tesis de licenciatura y maestría en el contexto de esta biblioteca. La biblioteca, por cierto, es una biblioteca para algoritmos bioinformáticos y estructuras de datos.

La biblioteca está construida en C ++ porque C ++ es casi perfecta para los requisitos específicos de esta biblioteca y para las bibliotecas de algoritmos en general. Si tuviera que desarrollar otra biblioteca de algoritmos y la elección del lenguaje fuera mía, seguramente elegiría C ++ nuevamente.

La razón no es solo el rendimiento, sino también el sólido sistema de tipos que, en primer lugar, le brinda más seguridad de tipos y, en segundo lugar, le permite dejar que sus tipos documenten el algoritmo utilizado. Esto puede (en mi experiencia) mejorar en gran medida la legibilidad y la facilidad de mantenimiento.

Dicho esto, para garabatos y acertijos algorítmicos simples, casi siempre uso Python (principalmente porque sí, se lee casi como un pseudocódigo), a menos que quiera probar específicamente cómo formular mejor un problema en C ++. Hasta ahora, no he resuelto muchos de los problemas de SPOJ o TopCoder, así que no sé si el rendimiento allí es realmente tan crítico que usar un lenguaje rápido es crucial.

Pero normalmente lo que cuenta es obtener el algoritmo correcto para pasar. En esos casos, Python funciona bien. Por ejemplo, para los problemas del Proyecto Euler (que no están cronometrados, solo cuenta la solución correcta), Python es perfectamente adecuado.

Konrad Rudolph
fuente