¿Es común hacer prototipos en un lenguaje de nivel superior? [cerrado]


18

Actualmente estoy jugando con la idea de embarcarme en un proyecto que supera con creces mi capacidad de programación actual en un lenguaje en el que tengo muy poca experiencia en el mundo real (C). ¿Sería valioso crear un prototipo en un lenguaje de nivel superior con el que estoy más familiarizado (como Perl / Python / Ruby / C #) solo para poder poner en marcha el diseño general?

En última instancia, el producto final es sensible al rendimiento (es un motor de base de datos), de ahí la elección de C, pero me temo que no saber C bien me hará perder el bosque por los árboles.

Mientras buscaba preguntas similares, noté que alguien mencionaba que los programadores solían prototipar en Prolog, luego lo sacaban en ensamblador.


44
He oído hablar de personas que escribirían ensamblador codificando primero lo que querían en C, luego desarmándolo y ajustando a mano el ensamblaje resultante.
user16764

99
No olvide que el rendimiento se reduce a menudo para corregir la selección e implementación de algoritmos, escribir código paralelo para problemas embarazosamente paralelos y buenas representaciones de datos. No se preocupe por C hasta que obtenga el diseño correcto.
Peter Smith

1
@ user16764: Realmente hice eso. Excepto que el idioma era Fortran. Pero modificamos manualmente la salida del compilador exactamente como usted describe.
S.Lott

C no es necesariamente más rápido. Especialmente si el rendimiento está sujeto a IO. Incluso para el rendimiento vinculado a la CPU, si no es un experto en C, una VM optimizada probablemente pueda superar a cualquier cosa que escriba usted mismo.
jiggy

A menudo uso esta técnica de creación de prototipos: un problema se expresa en su lenguaje más natural, que termina siendo implementado como un DSL. Luego, cuando el prototipo está terminado, en lugar de recodificar una parte DSL en un lenguaje de nivel inferior, mejoro la implementación de este compilador DSL, hasta que el rendimiento sea aceptable.
SK-logic

Respuestas:


27

El uso de C no hace que su aplicación sea más rápida automáticamente. Cuando tenga la capacidad de elegir un lenguaje de programación diferente para su plataforma, lo recomiendo encarecidamente.

Como Bill Harlan declaró :

Es más fácil optimizar el código correcto que corregir el código optimizado . La optimización prematura en realidad dificulta la optimización a largo plazo. La optimización innecesaria distorsiona los diseños, destruye la modularidad y la ocultación de información, y hace que el código sea mucho más difícil de modificar. Los errores latentes tardan más en encontrar. A menudo descubrimos mediante la creación de perfiles, o cambiando máquinas o compiladores, que juzgamos mal el esfuerzo computacional de nuestro código. ¿Adivina qué? Ahora, la optimización es mucho más difícil de lo que tenía que ser.

Si realmente puede predecir problemas de rendimiento, considere usar C ++. cprogramming.com lo expresa muy bien :

Usted podría preguntarse, sin embargo, si vale la pena renunciar a la reutilización de C ++ para obtener el pequeño incremento en el rendimiento con C, especialmente cuando C ++ pueden, en caso necesario, estar escrito en un estilo de programación C .


Para responder mejor a su pregunta real: escribiría código en un lenguaje de nivel superior, no solo prototipo, y solo optimizaría en idiomas de nivel inferior cuando encuentre problemas de rendimiento.


25
+1: Además, Perl, Python y Ruby pueden llamar a funciones de C, por lo que puede escribir las partes sensibles al rendimiento en C si es necesario.
Larry Coleman

He prototipado el código de visión artificial en Java; resultó que en realidad fue lo suficientemente rápido. Recodificación en C habría sido bastante fácil (que acaba de escribir es como C, mediante el uso de la fijación anti patrón primitivo)
Tim Williscroft

He escrito código en tiempo real en Java. En ese proyecto en particular, el acceso a los archivos se realizó con C ++, y el código en tiempo real estaba en Java, ¡loco! Sin embargo, el código en tiempo real fue increíblemente rápido. No fue muy complicado, pero manejó cantidades increíbles de datos en muy poco tiempo. Entonces, diría que definitivamente puede usar lenguajes de alto nivel para aplicaciones sensibles al rendimiento.
configurador

@Tim Williscroft: Parece que solo aparece esta página cuando busco en Google "antipattern de fijación primitiva". ¿Que es eso?
SingleNegationElimination

@TokenMacGuy: la obsesión primitiva tiene más éxitos (mismo antipatrón)
Tim Williscroft

7

No sería valioso hacer eso, porque a) las partes de esos lenguajes que se traducen directamente a C no serían más simples, yb) las partes que no se traducen directamente a C serían más difíciles de reescribir en C que si los hubiera escrito en C en primer lugar.


+1 - Especialmente porque sería difícil cambiar el código OO a C si no está familiarizado con el lenguaje, o haría que usar el lenguaje de alto nivel fuera más incómodo si escribe de manera procesal.
Jetti

Sí exactamente. Me preocupa que todavía pueda estar pensando en conceptos superiores que no se traducen fácilmente a C, como si uso demasiada magia o azúcar.
Mark Canlas

4

Esta no es una pregunta con una respuesta categórica de sí o no. Permíteme sopesar con una anécdota.

Ejemplo 1

Me encargaron portar un juego escrito en Java a Flash, AS3. En la superficie, esto tiene el potencial de ir relativamente sin problemas. Después de todo, podría considerar que dicho trabajo es más claro que el trabajo promedio de su cliente, porque ya tiene una especificación funcional completamente desarrollada en la forma del juego fuente. Java y AS 3 son lenguajes de alto nivel, y AS3 comparte muchos rasgos en común con Java, como estructuras de paquetes, herencia única / interfaz múltiple, tipeo fuerte (opcional) y nociones de variable pública / protegida / privada y declaraciones de funciones. En ese momento todavía era muy ecológico en Java, y completamente nuevo en la base de código fuente original. Así que me zambullí para ver qué podía encontrar con la esperanza de que fuera rápido y fácil.

Al final resultó que, el autor del código había intentado crear un motor abstracto que podría ser trasladado de Java a otro entorno indefinido. Esto me dio la esperanza de que sería sencillo portar. Desafortunadamente, lo que descubrí en su lugar fue que estaba considerando la posibilidad de reinventar Flash sobre Flash, sin el beneficio de Threads. Resultó que un puerto literal simplemente habría sido una mala idea ... una pesadilla de rendimiento. Además de eso, el juego implementó su propio lenguaje de secuencias de comandos externo personalizado, lo que habría significado crear un analizador y lexer para ese idioma si esperaba utilizar todos los archivos de datos de origen originales.

Al final, dadas las limitaciones de tiempo y presupuesto, el código fuente original realmente no ayudó mucho. La parte más útil de tenerlo fue que sabía cómo imitar con precisión el flujo de control de la lógica del juego ... pero ¿realmente necesitaba la fuente original para eso? Probablemente no.

Pero ese ejemplo puede no ser tan relevante porque es una especie de reverso de su situación. Esperaba usar una base de código que no escribí, en un lenguaje que en ese momento no conocía para acelerar el desarrollo en un entorno con el que estaba muy familiarizado. Aquí hay un ejemplo diferente

Ejemplo 2

Al darme cuenta de lo que estaba haciendo el desarrollador de Java al intentar crear una base de código portátil, me puse a hacer algo similar para mí en mi trabajo Flash ... escribir código que no dependiera tanto de extender las clases flash.display. *, Por ejemplo, y usando la composición para crear vistas. Sin depender tanto de flash.event. * Y, en cambio, escribir un sistema de transmisión de mensajes ligero propio, no vinculado especialmente a un idioma o plataforma. Recientemente terminé un juego usando dicho marco y quería ver si sería fácil portarlo a C # (un lenguaje que conozco tanto como es similar a Java y AS3) como un proyecto Unity 3D. ¡Resulta que esto fue mucho más exitoso! Porque pienso con más fluidez en AS3 que en C #, tener los algoritmos ya escritos ahorró una tonelada de tiempo. Todo lo que tenía que hacer era simplemente cambiar la sintaxis, que no es

Entonces, solo en mi propia experiencia personal, no puedo decir que la respuesta siempre será sí o no. Debe tener en cuenta cuán dependiente de las expresiones idiomáticas particulares que tenga en su idioma de alto nivel de elección, y si recrearlas será fácil o difícil en C.


Tu segunda historia ilustra cómo me siento. Trataría de mantener la implementación del prototipo genérica y libre de magia / trucos, de modo que la mayoría, si no todas, las ideas se puedan traducir a C. Más fácil decirlo que hacerlo, pero creo que a un nivel lo suficientemente alto todavía tiene. Obviamente el diablo está en los detalles.
Mark Canlas

@ Mark Canlas "el diablo está en los detalles". Absolutamente. Creo que es posible que su primer intento salga mal si nunca antes ha portado código entre idiomas o entornos solo porque es difícil prever todos los problemas potenciales hasta que los haya encontrado.
scriptocalypse

2

Creo que sería valioso comenzar con pseudocódigo. Escribir un prototipo en otro idioma parece una posible pérdida de tiempo, ya que es probable que su lenguaje de nivel superior no se traduzca a 'C' tan bien como lo hará el pseudocódigo.

Además, al usar pseudocódigo, desarrollará una mejor comprensión de cómo funciona realmente su sistema.

Durante el mismo período de tiempo en el que está trabajando en el pseudocódigo, debería estar estudiando C. Luego, para cuando haya terminado su planificación, podría estar listo para implementar realmente la cosa.

Dado que la razón propuesta para escribirlo en otro idioma fue para ayudar a poner en marcha el diseño, es posible que desee utilizar algunos diagramas UML o algo por el estilo para comenzar.


2

Puede crear un prototipo del algoritmo: resuelva los errores de diseño de la lógica central, utilizando definitivamente un lenguaje de "muy alto nivel" (por ejemplo, Matlab, tal vez Ruby). Úselo para demostrar que su algoritmo funciona y funciona correctamente, luego impleméntelo desde cero en un lenguaje de "bajo nivel".

No ganará mucho si elige C ++ o incluso Java o C # como "nivel alto" y C como "nivel bajo" porque la ganancia en legibilidad no será significativa y la "traducción" seguirá siendo bastante dolorosa y bastante defectuosa. propenso. La idea es la esencia, el motor de su proyecto en la implementación de alto nivel no debe ocupar más de una pantalla o dos, debe ser fácil de entender, fácil de leer y todas las advertencias deben ser dolorosamente obvias: esencialmente, un bloque funcional y ejecutable diagrama.


2

Un motor de base de datos se trata principalmente de manejar E / S de bajo nivel de una manera óptima y manejar estructuras complejas como b-tree y listas vinculadas de manera eficiente.

Por lo tanto, definitivamente es un problema de C / C ++, aunque hay algunas implementaciones de Java bastante buenas por ahí.

Desarrollar algoritmos correctos que funcionen bien es mucho más fácil en un lenguaje de nivel superior. Por lo general, se trata de probar varias variaciones y comparar los resultados. Luego puede traducir el algoritmo "ganador" a C.

Una solución de compromiso podría ser escribir la implementación inicial en uno de los lenguajes JVM de nivel superior (Jython, Groovy viene a mi mente) y luego mover clase por clase a Java cuando la implementación se estabilice.


2

No creo que sea común, pero está hecho. Uno de los arquitectos más hábiles con los que he trabajado solía modelar en Python y luego implementar ese código en C ++.

En general, para que esto valga la pena, creo que realmente se deben realizar algoritmos complejos y altamente optimizables que no se expresen fácilmente de una manera directa en el idioma de destino. Para la mayoría de las situaciones del "mundo real / negocios", es relativamente fácil expresar la intención de alto nivel en el mismo idioma al que nos dirigimos, y una implementación en dicho idioma cumple con nuestros requisitos de rendimiento, por lo que no hay necesidad / deseo de modelar en un nivel superior Nivel de lenguaje.

Dada su situación, donde tiene un mejor conocimiento de un lenguaje de nivel superior, podría ver esta metodología funcionando bien en el corto plazo. No solo le proporcionará una hoja de ruta para mantener el rumbo, sino que si tiene preguntas, podrá hacerlas con mayor precisión.


1

Actualmente estoy trabajando en un proyecto que está escrito en C "debido al rendimiento" (esta fue la motivación original), pero de hecho, si se describe, revela que pasa la mayor parte del tiempo esperando otros sistemas (un DB, otras aplicaciones escritas en Java, "eventos" en un socket).

Si utiliza el algoritmo incorrecto, también obtiene un mal rendimiento en C (por ejemplo, si realiza una búsqueda lineal de una clave, "dado que C no tiene tablas hash y no queremos utilizar otras bibliotecas", va más lento que si hazlo con un lenguaje que tenga tablas hash o similares como C ++, Java, C #, Python ... y así sucesivamente).

Si se ve obligado a hacerlo en C por cualquier razón, hacer prototipos en otro lenguaje que conozca no es una mala idea para mí solo si realiza un prototipo sabiendo qué "problemas" tendrá que hacer la implementación real de C, eso es difícil si no está seguro con C. (Pronto descubrirá, por ejemplo, que las bibliotecas estándar C / C no tienen contenedores, solo una matriz "simple"; necesita bibliotecas no estándar). Además, C no es OO, por lo que si realiza prototipos de manera OO, será más difícil.

Resumiendo, lo mejor que puede hacer es realizar la implementación real en su lenguaje de "creación de prototipos" y luego, si es realmente necesario, escribir funciones intensivas en CPU en C, pero si solo C es aceptable, aprenda mejor antes de hacer un prototipo en otro idiomas y, por supuesto, antes de escribir la implementación.


1

Hay muchas aplicaciones críticas de rendimiento escritas en un lenguaje de nivel superior.

He programado en Assembler y C en el pasado, y aunque es un poco genial sentirse tan cerca del metal, su uso es muy limitado hoy en día.

Hay tantas cosas que dificultarán el rendimiento, que dudo que alguna vez llegue a la parte donde el lenguaje en sí es el factor limitante. Esto está considerando que es C vs C #.

Supongamos que obtiene un 10% -15% de aumento de rendimiento por idioma. Esto no es nada comparado con el aumento de órdenes de magnitud para implementar el algoritmo correcto.

Cuando programe en C #, tendrá mucho más tiempo para concentrarse en la arquitectura y la implementación de algoritmos / estructuras de datos, lo que conducirá a mejores optimizaciones de nivel superior.

En el mundo real, siempre tiene limitaciones de tiempo, así que dedique su tiempo a la parte correcta del proyecto.


0

Tengo curiosidad por saber cuál es su plan para crearlo realmente en C? ¿Vas a crear un prototipo y luego aprender C, y luego volver a codificarlo en C? Para mí, esto se parece un poco a los proverbiales "ojos que son más grandes que el estómago", que creo que muchos programadores quedan atrapados mientras aprenden nuevas tecnologías (lo sé). Lo que quiero decir es que estás tratando de diseñar algo que sea claramente sensible al rendimiento sin saber aún los entresijos del lenguaje en el que crees que eventualmente necesita estar escrito, básicamente quieres comenzar a diseñar una aplicación C antes que tú. conozca C cuando se puede pasar mejor el tiempo aprendiendo primero C y luego puede obtener más información sobre cómo escribir la aplicación que desea. Tal vez confundí la pregunta y tiene la intención de pasar esto a otro programador para construir el programa en C,


A veces "No hagas eso". es la respuesta correcta a "¿Cómo hago X?"
Larry Coleman

0

La creación de prototipos se realiza, a veces, para comprender el problema que está tratando de resolver. Y a veces, para conocer las tecnologías subyacentes si aún no está familiarizado con ellas.

Para el caso mencionado, está considerando crear un prototipo en un lenguaje de script, por ejemplo, python, y crear el código real en C.

Evaluando algunas posibilidades:

1 . Tu prototipo en Python y escribes el software en C.

La creación de prototipos en un lenguaje de secuencias de comandos puede ayudar cuando desee comprobar rápidamente la salida con la entrada . Esto es útil si principalmente necesita probar su lógica para resolver un problema. Además, es útil si desea armar rápidamente una demostración para otras personas.

Cualquier código que haya escrito en python no se usará en el software final. Pero puede ayudar si le pasa su prototipo a alguien que puede leer python y escribir en C. Aquí, la creación de prototipos puede ayudar a comunicar una idea .

Este método es apropiado para probar la viabilidad lógica de la solución.

2 . Tu prototipo en C y escribes el software en C.

La creación de prototipos en C, que es nueva para usted, tiene dos ventajas. Uno, mientras que se escribe el prototipo, se llega a comprender las partes pertinentes de la lengua , biblioteca, API, trampas, etc. Dos, mientras se construye el software final, puede comenzar a partir del prototipo en sí lo que le ahorra tiempo y reutiliza código .

Este método se ajusta para probar la viabilidad lógica y tecnológica de la solución.

3 . Puede considerar formas de prototipos sin codificación según el problema en cuestión.

Si es una pieza de lógica e ideas que desea prototipar; el pseudocódigo , los diagramas de flujo y los diagramas de bloques en papel también son buenos.

Si es un prototipo de interfaz de usuario, considere alguna herramienta de maqueta de interfaz de usuario o, de nuevo, algo de papel.


0

Creo que debería crear un prototipo en un idioma con el que esté familiarizado (Pytho / Ruby / C # qué no) para que:

  1. Aproveche al máximo las instalaciones / bibliotecas que proporciona el idioma.
  2. Dedica su tiempo a decidir las opciones de diseño en lugar de las limitaciones de idioma.

Más tarde, puede usar una herramienta de creación de perfiles para encontrar áreas del cuello de la botella. Vuelva a implementar en C / C ++. Repita el paso anterior varias veces, ¡quién sabe que su prototipo podría ser 'lo suficientemente rápido'!


0

No creo que esté ganando nada con el enfoque que describió, y varias personas han descrito por qué con cierto detalle.

Un proyecto en el que he estado involucrado, utilizó este tipo de enfoque: desarrollo de la biblioteca matemática para las arquitecturas Cell / BE y Power7. Las funciones fueron modeladas en Haskell (usando CoCoNUT), y las funciones de salida estaban en ensamblaje optimizado para una arquitectura de destino particular.

En este caso, los objetivos eran un alto rendimiento con instrucciones de montaje ajustadas y la capacidad de apuntar a múltiples arquitecturas.

Sin embargo, comida, espero que no te mueras de hambre :)


0

Para un motor de base de datos de alto rendimiento, presumiblemente necesitará:

  • multihilo,
  • gestión explícita de la memoria,
  • notificaciones asincrónicas
  • semáforos o primitivas de sincronización,
  • Fácil acceso a las funciones del sistema de archivos de bajo nivel.

Los algoritmos que elija son críticos para el rendimiento.

El consejo general es comenzar con un lenguaje de alto nivel, luego migrar solo los bits que necesitan optimización a un lenguaje de nivel inferior.

Sin embargo , el lenguaje de alto nivel que elija debe ser compatible con los algoritmos que necesita para escribir: y los algoritmos eficientes aquí pueden estar dominados por el control de subprocesos, el uso eficiente de la memoria y el uso de las mejores operaciones de sistemas de archivos de bajo nivel disponible. Entonces, si el objetivo final es el rendimiento, no puede crear prototipos en idiomas que no admitan las primitivas que necesita usar.

Si necesita probar su prototipo (u otras personas necesitan desarrollar software contra sus interfaces), también debe trabajar en un lenguaje que admita las API previstas. Luego puede permitir que otras personas prueben su código y realicen sus propias pruebas de regresión mientras optimizan.

Estas consideraciones probablemente descarten muchos lenguajes para la creación de prototipos de alto nivel en este caso, y probablemente todos los que mencionó (excepto posiblemente C #). Pero, por supuesto, puede seudocódigo en cualquier idioma (incluido el inglés) y, si es necesario, puede crear prototipos de partes del proyecto (funciones de clasificación, por ejemplo) en su idioma preferido.

La estrecha relación entre C ++ y C (y las diferencias de rendimiento insignificantes) significan que hay muy pocas razones para no preferir C ++ sobre C en el producto final.

(Estoy respondiendo asumiendo que necesita un motor de base de datos de alto rendimiento para un propósito particular: si sus intenciones son más modestas, entonces presumiblemente estaría recogiendo un motor existente del estante).


-2

Creo que la fama de C es bien merecida, porque el magnífico producto Unix fue escrito en C. Sin embargo, en comparación con las personas que conocen mejor a C, soy bastante escéptico sobre por qué debería usarse. Se dice que Ken Thompson (después de escribir una primera versión de Unix en lenguaje ensamblador) comenzó a escribir Unix en Fortran, pero se dio por vencido después de una semana o un mes, y comenzó a usar C, que estaba desarrollando su colega Ken Ritchie en al mismo tiempo.

Me sorprendió leer recientemente que Fortran es más rápido que C y C ++.

Richard Mullins


1
¿Cómo responde esto a la pregunta que se hace?
mosquito
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.