Sieve en C3

Con Sieve en Javascript optimizado, había dado por cerrado el ciclo de rendimientos basados en Sieve en Java, BASIC, Pascal, y C.

Sin embargo después del buen sabor de boca con C3 (Clipper Compatible Compiler), me quedaba por comprobar como de bueno sería su rendimiento.

La clave de Clipper, era que generaba ejecutables nativos, pero que contenían un runtime de p-code para el código, que era interpretado. Esperaba por tanto que fuera menos eficiente que los lenguajes compilados tradicionales: C, Pascal, Basic, … Pero no sabía que tal se comportaría frente a Java o Javascript.

Tanto Java, como Javascript, son ejecutados actualmente con un compilador JIT, es decir, el sistema lee el código fuente, o bytecode, y genera código nativo en memoria, que es el que al final se acaba ejecutando.

El rendimiento obtenido ha sido bastante malo, y malísimo si tenemos en cuenta las buenas expectativas que tenía al ver lo compactos que eran los ejecutables. Ello me ha obligado a reducir las iteraciones a 10.000, las mismas que usé para Javascript, pero incluso con eso, ha resultado mucho menos veloz.

Incluso me planteé la posibilidad de que mis oxidados conocimientos de C3 hubieran causado que cometiese un error en la conversión del código.

He obtenido una medición de 136,83 segundos para el ejecutable x86, y de 149,17 segundos para el x64. Como digo, me ha sorprendido su falta de agilidad, con un desempeño 50 veces peor que el de Javascript, o lo que es lo mismo, 2.500 veces peor que C/C++.

Soy consciente que xBase no es el entorno ideal para el desarrollo de aplicaciones de cálculo intensivo, pero por esa misma regla de tres, tampoco lo es Javascript, y ahí están sus resultados más que dignos, que choca con el rendimiento ágil de la GUI, que también está escrita en C3.

Otro punto contradictorio es el hecho que la compilación de 64 bits resulte más lenta que la de 32 bits. Es obvio que no son necesarios grandes números en el algoritmo de Sieve, y que los punteros largos tendrán cierta sobrecarga, pero también es verdad que tenemos más registros de CPU disponibles, y una convención de llamada más eficiente, que deberían igualar ambas plataformas. Quizás el problema venga por el generador de código de Visual C++ 2005 con el que está implementado el núcleo de C3, que no sea demasiado eficaz en 64 bits. Valdría la pena actualizar a 2013 o 2014 CTP, y ver si la cosa mejora.

Como es habitual, os dejo el código aquí para que lo reviséis vosotros mismos:

#define MAXITER 10000
 
procedure main
   local i, k
   local found, iter
   local flags[MAXITER]
   local start, finish
 
   ? str(MAXITER) + " iterations"
   start := seconds()
   for iter := 1 to MAXITER
           found := 0
           for i := 1 to MAXITER
                  flags[i] := 0
           next i
           for i := 2 to MAXITER
         if flags[i] = 0      // found a prime
                      found++
            for k := i+i to MAXITER step i
               flags[k] := 1
            next
                  endif
           next
   next
   finish := seconds()
   ? str(found) + " primes in " + str((finish-start)*1) + " seconds "
return

Y os dejo el proyecto, los fuentes, y los binarios de 32 y 64 bits aquí (195 Kb. en formato ZIP).

Esperemos que poco a poco el runtime vaya mejorando en eficiencia.

6 comentarios en “Sieve en C3”

  1. Efectivamente Adrián Arroyo Calle.

    Actualmente tengo Sieve implementado en unos 7 lenguajes, y aproximadamente 10 dialectos. Uno de los siguientes candidatos tiene números de ser Lua, del que algo he tocado.

    Del resto de tus interesantes sugerencias, serán probablemente con el tiempo, pues de momento, con la salvedad de haber leído acerca de ellos, y visto algo de código, no tengo ninguna soltura.

  2. Si quieres probar xbase, seguramente la mejor opción a día de hoy sea Harbour (http://harbour.github.io).

    Aquí tienes el mismo programa sieve con Xailer (http://www.xailer.com) + Harbour + MinGW: http://ge.tt/api/1/files/7nHwX3o1/0/blob?download

    En mi i5 ha tardado 51.98 segundos frente a los 102.87 segundos de c3 en 32 bit. Redondeando es el doble de rápido. Todavía está muy lejos de otros lenguajes, pero dentro del mundo xbase la elección está clara. Xbase nunca se diseñó para hacer cálculos intensivos, sino para hacer aplicaciones de negocios, y en ese nicho funciona muy bien.

  3. He probado tu compilado, y en mi entorno ha dado una mejora también del doble comparado con C3 anonimo. La contrapartida es que el tamaño del ejecutable, es casi 3 veces superior al de C3.

    He verificado el código de tu Sieve.prg, y efectivamente es idéntico al mío, con las excepciones lógicas de la librería de Xailer, pero con tu permiso lo pongo aquí, que a alguien le resultará interesante.

    /*
     * Proyecto: Sieve
     * Fichero: Sieve.prg
     * Descripción: Módulo de entrada a la aplicación
     * Autor:
     * Fecha: 12/07/2014
     */
     
    #include "Xailer.ch"
     
    Procedure Main()
     
       Application:cTitle := "Sieve"
       Sieve()
       Application:Run()
     
    Return
     
    #define MAXITER 10000
    #command ? <x> => MsgInfo( </x><x> )
     
    procedure Sieve()
     
       local i, k
       local found, iter
       local flags[MAXITER]
       local start, finish
     
       ? str(MAXITER) + " iterations"
       start := seconds()
       for iter := 1 to MAXITER
               found := 0
               for i := 1 to MAXITER
                      flags[i] := 0
               next i
               for i := 2 to MAXITER
             if flags[i] = 0      // found a prime
                          found++
                for k := i+i to MAXITER step i
                   flags[k] := 1
                next
                      endif
               next
       next
       finish := seconds()
       ? str(found) + " primes in " + str((finish-start)*1) + " seconds "
     
    return</x>
  4. Jhonny Villarroel, aquí puedes encontrar la última versión publicada de CA-Clipper, la 5.3b, así como otras más antiguas: http://vetusware.com/download/CA-Clipper%205.3b%20Intl/?id=8460

    Efectivamente era excelente, no sólo con el DBEdit, sino con los drivers de base de datos reemplazables (RDD), …

    Si tienes nostalgia, puedes leer el artículo sobre Clipper y Blinker que publiqué.

    Espero que te sirva! Ya nos irás contando.

Deja un comentario