Frikis, mensajes navideños, cadenas en hexadecimal y computación concurrente

El megafriki de Pablo Alvarez Doval, nos envió una felicitación navideña códificada con caractéres hexadecimales. Cualquier persona normal hubiese pegado la felicitación en un editor de texto un poco potente y hubiese visto lo que decía. Pero el amigo Octavio Hernandez abrió la caja de Pandora: mando un método extensor para la clase String que descodificaba el mensaje.


Yo no he podido menos que recoger el guante e implementar mi propia solución al problema. He tratado de hacer algo original ,no eficiente, de hecho la solución de Octavio (que espero que publique en su blog) es infinitamente más eficiente. Yo he decidido usar paralelización, usando Microsoft Parallel Extensions, siguiendo mi proposito de este año de actualizar mis conocimientos de programación concurrente.


Dada la cadena en hexadecimal del mensaje, se hace evidente que la conversión de cada uno de los caracteres desde su represantación hexadecimal a un valor de tipo char es un operación atómica e independiente para cada caracter. Sin duda es una buena ocasión de usar programación concurrente (aunque a nadie se le debería ocurrir usar esto en un escenario real, el coste de la paralelización anula cualquier ventaja de rendimiento, en casos donde cada operación independiente tiene un coste mínimo como es el caso).



    1 using System;


    2 using System.Diagnostics;


    3 using System.Threading;


    4 


    5 namespace ParallelDecode


    6 {


    7   class Program


    8   {


    9     const string message =


   10       «%46%65%6C%69%63%65%73%20%46%69%65%73» +


   11       «%74%61%73%2C%20%63%61%63%68%6F%20%66» +


   12       «%72%69%6B%69%21%20%41%68%6F%72%61%2C» +


   13       «%20%64%65%6A%61%74%65%20%64%65%20%74» +


   14       «%6F%6E%74%65%72%69%61%73%20%79%20%76» +


   15       «%65%74%65%20%61%20%65%6D%62%6F%72%72» +


   16       «%61%63%68%61%72%74%65%20%75%6E%20%70» +


   17       «%6F%71%75%69%6E%21%21%20%4B%65%65%70» +


   18       «%20%52%6F%63%6B%69%6E%27%21%21»;


   19 


   20     static void Main(string[] args)


   21     {


   22       Stopwatch sw = new Stopwatch();


   23       sw.Start();


   24 


   25       string[] splitedMessage = message.Split(‘%’);


   26 


   27       char[] result = new char[splitedMessage.Length – 1];


   28 


   29       Parallel.For(0, result.Length, i =>


   30         {


   31           result[i] = (char)(int.Parse(splitedMessage[i + 1], System.Globalization.NumberStyles.AllowHexSpecifier));


   32         }


   33       );


   34 


   35       sw.Stop();


   36 


   37       Console.WriteLine(result);


   38       Console.WriteLine(«Tiempo de proceso: {0} ms.», sw.ElapsedMilliseconds);


   39 


   40       Console.ReadKey();


   41     }


   42   }


   43 }


En un post reciente me preguntaba si las abstracciones que se están construyendo serían lo suficientemente simples para facilitar la programación concurrente al comuún de los mortales… parece que sí, pues el código no puede ser más simple y desde luego es muchísimo más simple usar Parallel Extensions que la que hacer lo mismo usando hilos. La clase Parallel nos propociona mecanismos sumamente potentes y simples a la hora de añadir paralelización a porciones iterativas de nuestro código sin esfuerzo alguno.


¿Alguien más se anima a publicar otras soluciones diferentes al problema? ¿Quizás con LINQ o PLINQ? ¿Alguien con F#? ¿Alguien con T-SQL?…

10 comentarios sobre “Frikis, mensajes navideños, cadenas en hexadecimal y computación concurrente”

  1. Estáis todos fatal!! 😛

    Por cierto, el último sw.Start() no debería ser un sw.Stop() ?

    Me tendré que mirar esto de las parallel extensions porque hacen buena pinta…

    Buenas fiestas!!

  2. Sería guay que estas estas extensiones pudieran sacar partido de la capacidad de computación en paralelo de las GPU, al estilo de CUDA. ¿has leído algo al respecto?. Saludos.

  3. @JVenero: Por lo que voy leyendo sobre Parallel Extensions, que es bastante en los últimos días, no creo que aprovechen la GPU. Creo que la Parallel Task Library está a un nivel de abstracción mayor. En .Net creo que si se decide usar la GPU sería algo que se implementería a un nivel mucho más bajo, quizás en el jitter… pero yo no soy un experto en compiladores, quizás este diciendo una barbaridad.

    Me parece que tienen sentido el pensar que si se usa la GPU no se use solo en escenarios de concurrencia sino en general cuando sea necesaria gran potencia de cálculo, por ejemplo en operaciones criptográficas, SSL, etc… Creo que de esto sabes más tu que yo ¿te parece factible lo que comento?…

    ¡Un saludo titán!

  4. #!/usr/bin/perl -w

    use strict;

    my $D = «46656C6963657320466965737461732C20636163686F206672696B69212041686F72612C2064656A61746520646520746F6E74657269617320792076657465206120656D626F72726163686172746520756E20706F7175696E2121204B65657020526F636B696E272121»;

    print pack(«H*», $D);

  5. Perl!!!! Jjajajaj… muy bueno… pero has hecho un poco de trampa, no valía cambiar la cadena del mensaje!!!

    De todos modos, queda clara la potencia del Perl para este tipo de cosas….

    ¡Gracias por la aportación!

  6. Con un poco de trampas (aprovechando que usa el formato definido en:
    http://tools.ietf.org/html/rfc3986#section-2.1
    ):

    #!/usr/bin/env python

    message = «%46%65%6C%69%63%65%73%20%46%69%65%73%74%61%73%2C%20%63%61%63%68%6F%20%66%72%69%6B%69%21%20%41%68%6F%72%61%2C%20%64%65%6A%61%74%65%20%64%65%20%74%6F%6E%74%65%72%69%61%73%20%79%20%76%65%74%65%20%61%20%65%6D%62%6F%72%72%61%63%68%61%72%74%65%20%75%6E%20%70%6F%71%75%69%6E%21%21%20%4B%65%65%70%20%52%6F%63%6B%69%6E%27%21%21»

    import urllib
    print urllib.unquote(message)

    Otra solución igual sirve:

    message = «%46%65%6C%69%63%65%73%20%46%69%65%73%74%61%73%2C%20%63%61%63%68%6F%20%66%72%69%6B%69%21%20%41%68%6F%72%61%2C%20%64%65%6A%61%74%65%20%64%65%20%74%6F%6E%74%65%72%69%61%73%20%79%20%76%65%74%65%20%61%20%65%6D%62%6F%72%72%61%63%68%61%72%74%65%20%75%6E%20%70%6F%71%75%69%6E%21%21%20%4B%65%65%70%20%52%6F%63%6B%69%6E%27%21%21″
    print ».join([ chr(int(h,16)) for h in message.split(‘%’)[1:] ])

Responder a rcorral Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *