Archivo de la etiqueta: Delphi

TStopWatch y cómo medir tiempos con alta precisión con Delphi

Las versiones modernas de Delphi cuentan con la unidad System.Diagnostics que implementa la clase TStopWatch, un cronómetro de alta precisión con el que podemos medir fácilmente el desempeño del código que escribimos, con soporte multiplataforma.

TStopWatch es un registro que tiene métodos para iniciar, pausar y resetear el cronómetro (muy similar a los botones que encontramos en el cronómetro de pulsera promedio).

Cuando digo alta precisión, hablamos de que la resolución del cronómetro suele estar en el orden de los nano-segundos o incluso fracciones de nanosegundo (esta puede variar de un procesador a otro). En mi equipo de desarrollo actual (Corei7 8va Generación/Windows 10), el menor tiempo que he podido medir es de 0.1 nanosegundos, la idea básica sería algo como:

procedure TForm3.Button1Click(Sender: TObject);
var
  SW: TStopwatch;
begin
  SW := TStopwatch.Create;
  SW.Start;
  SW.Stop;
  Memo1.Lines.Add(Format('Ticks: %d, Frequency: %d', [SW.ElapsedTicks, sw.Frequency]));
  Memo1.Lines.Add(SW.Elapsed.ToString);
end;

Ya con esta idea básica podemos medir, entonces, el tiempo que tarde cualquier fragmento de código, por ejemplo:

procedure TForm3.Button1Click(Sender: TObject);
var
  SW: TStopwatch;
  I, J: Integer;
begin
  J := 0;
  SW := TStopwatch.Create;
  SW.Start;
  for I := 1 to 1000000 do
    J := J + I;
  SW.Stop;
  Memo1.Lines.Add(Format('J: %d', [J]));
  Memo1.Lines.Add(Format('Ticks: %d, Frequency: %d, ms: %d, ns: %.6f', [SW.ElapsedTicks, sw.Frequency, SW.ElapsedMilliseconds, SW.ElapsedTicks/sw.Frequency*1000000]));
  Memo1.Lines.Add(SW.Elapsed.ToString);
end;
Resultados de la ejecución del código

Pensando como bibliotecarios, podemos declarar una función que se encargue de realizar la medición de cualquier código por nosotros, por ejemplo:

function MedirTiempoDe(Proc: TProc): TTimeSpan;
var
  SW: TStopwatch;
begin
  SW := TStopwatch.StartNew;
  Proc();
  SW.Stop;
  Result := SW.Elapsed;
end;

En una futura entrada veremos como crear una biblioteca de medición de tiempos robusta basados en TStopWatch.

Código de ejemplo de la sesión de DataSnap en CodeRage América Latina 2014

CodeRage Latinoamérica 2014

En relación a mi presentación en el reciente CodeRage América Latina 2014, titulada:

Aplicaciones iOS y Android con soporte para arquitecturas Multi-capas utilizando DataSnap

Haciendo clic en el botón, puedes descargar el código del ejemplo que se desarrolló durante la misma
Sigue leyendo

Clase genérica para convertir una enumeración en cadena y viceversa

Una de las cosas que siempre olvido como hacer, y por lo mismo me toca hacer una búsqueda en Google para volver a escribir el código necesario, es como convertir una enumeración en un string y viceversa (EnumToStr, StrToEnum).

Esto es, primero, porque tradicionalmente hay que escribir una rutina distinta para cada tipo de enumeración que nos interesa, o peor aún, escribir una llamada directamente a GetEnumName/GetEnumValue, que son las que hacen el trabajo sucio.

También esto se debe, en parte, porque hasta ahora no se me había ocurrido la idea de valerme de los genéricos para tener un trozo de código que sea re-utilizable y meter mi rutina en alguna biblioteca de las que suelo tener a mano mientras escribo código.

Ya con la idea, y luego de algún esfuerzo, escribí la clase que ahora les comparto, pero primero, veamos su uso, que vendría a ser, por ejemplo:

begin
  Memo1.Lines.Add(
    TEnumConverter<TAlign>.ToString(Self.Align));
end;

Sigue leyendo

Delphi para Android es una realidad

AndroidHelmetHoy, a primera hora de la mañana, Embarcadero ha realizado el anuncio oficial de RAD Studio XE5, la primera versión de RAD Studio y Delphi que incluye soporte para compilar proyectos para Android, la plataforma móvil más utilizada en nuestros días. Este compilador viene a sumarse a los tradicionales compiladores para Win32, Win64, y a los más recientes, para OSX e iOS de la herramienta.

No puedo ocultar que estoy muy emocionado, con grandes expectativas para esta nueva versión de Delphi, sobre la que hay mucho por decir y en la que se enfocarán mis próximas publicaciones.

Por ahora, la idea de esta corta entrada, es hacer eco de la noticia y dejarte estos enlaces oficiales de Embarcadero, donde encontrarás más información (en inglés):

RAD Studio XE4 está aquí

delphihelmet100x100

El día de hoy ha sido anunciado oficialmente el lanzamiento de RAD Studio XE4 y Delphi XE4, cuya principal novedad es el soporte para desarrollo de aplicaciones nativas para iOS, basado en un nuevo compilador, conocido como nextgen que debuta en su versión para procesadores ARM, y utilizando FireMonkey3 como plataforma de desarrollo visual

Por ahora estoy corto de tiempo para entrar en detalles de esta nueva entrega, que son muchos, pero si estas interesado en el desarrollo multi-dispositivo, esta es, con seguridad, la versión de Delphi que estabas esperando, así que te invito a probarla!

Actualización del libro Programación paralela con OmniThreadLibrary

Portada del libroEl día de hoy, luego de algunos meses de espera, se ha publicado la versión actualizada del libro Programación paralela con OmniThreadLibrary.

Esta versión contiene ya culminado el capítulo 5: Sincronización, que habla sobre algunas primitivas de sincronización disponibles en la biblioteca, y vuelve a estar al día con la versión en Inglés. Todos los lectores anteriores pueden realizar la descarga de esta nueva versión sin costo alguno, desde su página de administración de compra, en Leanpub.com.

Si aún no has comprado el libro, ¿qué esperas? 😀

FastMM, FullDebugMode y Fugas de memoria

delphihelmet100x100

Hoy, 14 de febrero de 2013, Delphi alcanza la mayoría de edad. A todos
los que trabajan con esta herramienta:

¡Felices 18 años de Delphi!

FastMM 4

Por si no lo sabes, FastMM es un manejador de memoria de código abierto, desarrollado por Pierre le Riche como reemplazo al manejador de memoria de Borland utilizado en Delphi desde el inicio, y que se convirtió en el manejador de memoria por defecto a partir de Delphi 2006.

Eso significa que, si utilizas Delphi 2006 o superior, ya estas usando FastMM, pero probablemente no estás sacando todo el provecho que podrías de él

En este artículo no hablaremos a profundidad sobre las ventajas de FastMM, ni lo compararemos con otros manejadores de memoria existentes. Por hoy, nos centraremos en la opción FullDebugMode de FastMM y veremos como este modo nos ayuda a resolver las fugas de memoria que puede haber en nuestras aplicaciones

Sigue leyendo

7zip y Delphi

7ziplogoHoy me dí a la tarea de buscar la manera de trabajar con archivos 7zip desde Delphi.

Encontré así la biblioteca d7zip, publicada bajo licencia MPL1.1, lo cual en pocas palabras, nos permite hacer uso de ella en proyectos libres o privativos.

A pesar de que la biblioteca no ha publicado nuevas versiones desde Abril del 2010 (v.1.2), el log de SVN muestra alguna actividad aún en noviembre del 2011 y es compatible con las últimas versiones de Delphi, lo cuál me pareció aceptable para considerarlo un proyecto vivo.

Antes de decidirme a utilizarla, quise comprobar si encontraría algún problema para compilar y ejecutar aplicaciones de 64 bits con esta, tomando en cuenta que la descarga incluye únicamente la versión de 32 bits para el archivo 7z.dll (versión 4.65).
Sigue leyendo

Delphi XE2/XE3 – Creando aplicaciones VCL con estilo

A partir de Delphi XE2 y ahora también en XE3, las aplicaciones Delphi contienen un nuevo motor de Temas y Estilos.

Esto significa que podemos hacer una aplicación visualmente más atractiva sin prácticamente ningún esfuerzo, y también que podemos añadir nuestro propio estilo personalizado a las aplicaciones.

Por hoy, veremos de manera rápida cómo realizar una aplicación con un estilo diferente en Delphi, cómo podemos interrogar a la propia aplicación sobre los estilos disponibles y cómo podemos, en tiempo de ejecución, cambiar de estilo.

Pero, primero, veamos el resultado de compilar nuestra sencilla aplicación Demo y ejecutarla:

Formulario con estilo

Sigue leyendo

La clase TIdMessageBuilderHtml y el envío de correos HTML desde Delphi

Hay muchas formas de enviar correos con Delphi.

Mi preferida desde hace tiempo es hacerlo vía SMTP con la clase TIdSMTP, que es flexible y poderosa.

Hoy, a raíz de que mi estimado amigo, Edgar Ramírez, publicara su artículo Enviar correo con imágenes incrustadas con Delphi he recordado que hace tiempo me gustaría iniciar una serie de artículos sobre el uso de INDY y la comunicación TCP/IP con Delphi.

A manera de respuesta a la publicación citada, quiero mostrar cómo realizar el envío de un correo similar —con una imagen incrustada— haciendo uso de la clase auxiliar TIdMessageBuilderHtml, que en mi opinión no solo facilita las cosas sino que nos deja una solución mucho más elegante y fácil de entender en el código.

La parte relevante del envío de correo es:

<br>
procedure TfrmCorreo.EnviaCorreoImagen(const FileName: string);<br>
var<br>
  Builder: TIdMessageBuilderHtml;<br>
  Msg: TIdMessage;<br>
  SMTP: TIdSMTP;<br>
begin<br>
  Builder := TIdMessageBuilderHtml.Create;<br>
  try<br>
    Builder.Html.Add('&lt;HTML&gt;&lt;HEAD&gt;&lt;TITLE&gt;Una imagen para ti&lt;/TITLE&gt;&lt;/HEAD&gt;&lt;BODY&gt;');<br>
    Builder.Html.Add('&lt;p&gt;&lt;strong&gt;Una imagen para ti&lt;/strong&gt;&lt;/p&gt;');<br>
    Builder.Html.Add('&lt;div&gt;');<br>
    Builder.Html.Add('  &lt;img border="0" src="cid:laimagen" &gt;');<br>
    Builder.Html.Add('&lt;/div&gt;');<br>
    Builder.PlainText.Add('Este correo contiene una imágen para ti. '<br>
      + 'Debes usar un visor HTML para verla');<br>
    Builder.HtmlFiles.Add(FileName, 'laimagen');<br>
    Msg := Builder.NewMessage();<br>
    try<br>
      Msg.Recipients.EMailAddresses := eRecipients.Text;<br>
      Msg.From.Name := eFromName.Text;<br>
      Msg.From.Address := eFromEmail.Text;<br>
      Msg.Subject := 'Una imagen para ti';<br>
      SMTP := TIdSMTP.Create;<br>
      try<br>
        SMTP.Host := eSMTPHost.Text;<br>
        SMTP.Username := eSMTPUser.Text;<br>
        SMTP.Password := eSMTPPass.Text;<br>
        SMTP.Connect;<br>
        try<br>
          SMTP.Send(Msg);<br>
        finally<br>
          SMTP.Disconnect;<br>
        end;<br>
      finally<br>
        SMTP.Free;<br>
      end;<br>
    finally<br>
      Msg.Free;<br>
    end;<br>
  finally<br>
    Builder.Free;<br>
  end;<br>
end;<br>

Como puede observarse, la instancia de TIdMessageBuilderHtml se encarga de los detalles sobre adjuntar los archivos. De lo que debemos asegurarnos es de proveer un cid diferente para cada imagen incluida en el HTML de nuestro correo, y que estos identificadores se correspondan con los archivos incluidos posteriormente en la llamada al método HtmlFiles.Add, que recibe como parámetros el nombre del archivo y el cid correspondiente.

Aclaración: En mi opinión cualquier método con más de 25 líneas de código es demasiado grande y debe considerarse su refactorización. Es el caso del código publicado, sin embargo he preferido mantener un solo método para no enredar al lector con tener que seguir mentalmente las llamadas entre ellos. Como se ve, el método se encarga de todo el envío del correo, lo cuál conceptualmente también puede ser mucho para un solo método. En algo para producción, esto probablemente sería dividido en 3 distintos métodos: armar el correo HTML, configurar el mensaje y finalmente la conexión/envío/desconexión.

Editado el 1/7/2021

La unidad a incluir en la cláusula uses es IdMessageBuilder. Lo agrego aquí, porque sin querer he omitido la información en la entrada y hay varios comentarios de algunas personas que no encuentran la clase. La unidad está en la carpeta Protocols de Indy.