Mostrando las entradas con la etiqueta Bytes. Mostrar todas las entradas
Mostrando las entradas con la etiqueta Bytes. Mostrar todas las entradas

domingo, 29 de mayo de 2022

Los 10 Mandamientos de la Performance en Desarrollo Web por Luis Duenas (Versión Posters)

 Poster en Castellano


Poster en Ingles



Los 10 Mandamientos de la Performance en Desarrollo Web por Luis Duenas

Comentario Inicial

Un problema frecuente en la programación es la falta de rendimiento o velocidad (Performance) en aplicaciones web y esto se debe a que existen principios que si no los sigues te esperan muchos problemas (aunque al programador no le afecta directamente sino mas bien a los usuarios).

Muchos creen conocer o programar bien pero desconocen estas reglas esenciales en el desarrollo web, por este motivo voy a publicar los 10 mandamientos de la performance en el desarrollo web que te ayudaran a mejorar tus aplicaciones.

Síntomas que indican que los programadores no conocen sobre Performance Web

A continuación te listo algunos síntomas que indican que los programadores no conocen sobre performance web:

1. Las paginas web demoran en cargar

2. Las consultas demoran en mostrarse, sobre todo si tienen cientos o miles de registros

3. La grabación de un registro con muchos campos demora

4. La grabación de varios registros demora

5. La subida de un archivo grande se demora mucho y sobre todo cuando tiene muchos Megabytes nunca se sube y se cae

6. Cuando hay poco ancho de banda no carga la data.

7. Si son muchas imágenes se muestran con lentitud, etc.

Los 10 Mandamientos del Compendio del Catecismo de la Iglesia Católica

Antes de iniciar con la lista, recordemos los 10 Mandamientos del Compendio del Catecismo de la Iglesia Católica:

1. Amarás a Dios sobre todas las cosas.

2. No tomarás el nombre de Dios en vano.

3. Santificarás las fiestas.

4. Honrarás a tu padre y a tu madre.

5. No matarás.

6. No cometerás actos impuros.

7. No robarás.

8. No darás falsos testimonios ni mentirás.

9. No consentirás pensamientos ni deseos impuros.

10. No codiciarás los bienes ajenos.

Los 10 Mandamientos de la Performance en Desarrollo Web

1. En desarrollo Web, elegirás la Performance sobre todas las demás características, tales como Seguridad, Reusabilidad, Mantenibilidad, Responsividad, etc.

2. No harás request en vano. Ni al Servidor Web ni a la Base de Datos, ni a cualquier recurso del Backend. Para esto debes agrupar llamadas al Servidor Web y agrupar lógica en solo un Procedimiento Almacenado en vez de varios.

3. Ahorraras al máximo el ancho de banda. Al hacer get (recibir) o post (enviar) debes reducir los datos seleccionando el mejor formato entre los cuales están: HTML, XML, JSON, CSV, Bytes. A veces es necesario comprimir y descomprimir si no demora.

4. Honrarás la simplicidad en vez de la complejidad y la generalidad en vez de la especificidad del desarrollo. Esto te permitirá reducir el código y te servirá para muchos casos de uso.

5. No matarás la Memoria usando decenas o cientos de variables de todo tipo y funciones en la pila usando excesivas capas de código. También, no matarás la CPU usando bucles excesivos ni recursividad sobre todo en el servidor.

6. No cometerás exceso en el uso de librerías y frameworks que harán mas pesado tu desarrollo. Es preferible crear solo la funcionalidad que necesites en vez de usar algo que viene con cientos de funciones que no las vas a usar y te consumirán mucha memoria.

7. No bloquearas los recursos del backend en llamadas concurrentes al servidor web, base de datos y sistema de archivos. Para esto debes hacer uso de programación asíncrona, paralela y trabajar en memoria en vez de disco.

8. No mentirás a tus usuarios diciendo que las aplicaciones web demoran porque no están locales y hay que viajar hasta el servidor web justificando la demora por falta de conocimiento de técnicas de performance.

9. No consentirás que ninguna tarea demore aunque el ancho de banda sea reducido, para lo cual debes hacer uso de trabajo por bloques sea al enviar o recibir. Puedes optimizar imágenes, crear paquetes de bytes, comprimir, etc.

10. No codiciarás ni envidiarás el código de terceros tales como Librerias y/o Frameworks aunque sea de grandes empresas. Lo mejor es que aprendas a crear tus propios recursos y el desarrollo será cada vez mas rápido. No te dejes influenciar por lo que la mayoría hace y trata de comprobar si es verdad lo que se dice.

Comentario Final

Los que no respeten dichos mandamientos serán considerados pecadores del desarrollo web y les espera el infierno de la lentitud de su aplicación, quejas de los usuarios y la consiguiente perdida para el negocio.

Al igual que en la religión donde la mayoría de personas no cumplen los mandamientos de la Iglesia Católica (siendo católicos), en el desarrollo web los programadores no cumplen ninguna de estas reglas y después se quejan de que sus sistemas están lentos.

Sino quieres que a ti o algún conocido le espere el Infierno de la web comparte esta publicación para que los programadores lo tengan en cuenta.

lunes, 5 de enero de 2015

El Demo del Día: Leer y Escribir la Metadata de un Archivo MP3

Leer y Escribir la Metadata de un Archivo MP3

Primer Demo del año, después de un largo periodo sin publicar ejemplos en el Blog. En esta ocasión vamos a ver como podemos leer y escribir la información (metadata) de un archivo MP3.

La especificación que define la metadata de un archivo MP3 se llama ID3 y están disponibles 2 versiones: ID3V1 y ID3V2. En este demo veremos como crear una aplicación que permita leer y escribir el ID3V1.

Existen Librerías en C# que permiten manejar el ID3, tales como:
TagLib
ID3Net
C#ID3Lib

Pero como el lema de este Blog es "Hazlo tu mismo", veremos como crear nuestra propia aplicación WinForms en C#, para lo cual debemos saber que los últimos 128 bytes de un archivo MP3 se usan para el ID3V1, es decir, para guardar información del archivo (Metadata).

La estructura seria la siguiente, para los últimos 128 bytes de un archivo MP3:
- Cabecera: 3 bytes (por ejemplo para el ID3V1 la palabra: TAG)
- Titulo: 30 bytes
- Artista: 30 bytes
- Album: 30 bytes
- Año: 4 bytes
- Comentario: 30 bytes que se dividen en 3 partes:
  -) Comentario: 28 primeros bytes
  -) Tiene Pista: 1 byte (0 si tiene numero de pista)
  -) Numero de Pista: 1 byte (numero de pista o track)
- Genero: 1 byte (Entero de 0 a 255 con los géneros, los cuales enumero en el código)

Teniendo estos conceptos claros ahora crearemos una aplicación que permita seleccionar un archivo MP3 y leer la información de la metadata y poder grabarla si se realiza cambios, para lo cual trabajaremos con archivos.

Crear una Aplicación WinForms en C#

Crear una Aplicación WinForms en C# llamada "Leer_Escribir_ID3_MP3" y al formulario cambiarle de nombre a "frmInfoMP3" y diseñarlo como se muestra en la siguiente figura:



Crear una Clase con la estructura de la MetaData del MP3

Agregar una clase a la aplicación llamada: "MP3ID3Tag" para almacenar la metadata y escribir el siguiente código:

namespace Leer_Escribir_ID3_MP3
{
    public class MP3ID3Tag
    {
        public byte[] Id = new byte[3];
        public byte[] Titulo = new byte[30];
        public byte[] Artista = new byte[30];
        public byte[] Album = new byte[30];
        public byte[] Año = new byte[4];
        public byte[] Comentario = new byte[30];
        public byte[] Genero = new byte[1];

        public enum Generos
        {
            Blues =0,
            Classic_Rock =1,
            Country=2,
            Dance=3,
            Disco=4,
            Funk=5,
            Grunge=6,
            HipHop=7,
            Jazz=8,
            Metal=9,
            New_Age=10,
            Oldies=11,
            Other=12,
            Pop=13,
            Rhythm_And_Blues=14,
            Rap=15,
            Reggae=16,
            Rock=17,
            Techno=18,
            Industrial=19,
            Alternative=20,
            Ska=21,
            Death_Metal=22,
            Pranks=23,
            Soundtrack=24,
            Euro_Techno=25,
            Ambient=26,
            Trip_Hop=27,
            Vocal=28,
            Jazz_Funk=29,
            Fusion=30,
            Trance=31,
            Classical=32,
            Instrumental=33,
            Acid=34,
            House=35,
            Game=36,
            Sound_Clip = 37,
            Gospel=38,
            Noise=39,          
            Alternative_Rock = 40,
            Bass=41,
            Soul=42,
            Punk_Rock=43,
            Space=44,
            Meditative=45,
            Instrumental_Pop=46,
            Instrumental_Rock = 47,
            Ethnic=48,
            Gothic=49,
            Darkwave=50,
            Techno_Industrial=51,
            Electronic=52,
            Pop_Folk=53,
            Eurodance=54,
            Dream=55,
            Southern_Rock=56,
            Comedy=57,
            Cult=58,
            Gangsta=59,
            Top_40=60,
            Christian_Rap=61,
            Pop_Funk=62,
            Jungle=63,
            Native_American=64,
            Cabaret=65,
            New_Wave=66,
            Psychedelic=67,
            Rave=68,
            Showtunes=69,
            Trailer=70,
            Lo_Fi=71,
            Tribal=72,
            Acid_Punk=73,
            Acid_Jazz = 74,
            Polka=75,
            Retro=76,
            Musical=77,
            Rock_And_Roll=78,
            Hard_Rock=79,
            Folk=80,
            Folk_Rock=81,
            National_Folk=82,
            Swing=83,
            Fast_Fusion=84,
            Bebop=85,
            Latin=86,
            Revival=87,
            Celtic=88,
            Bluegrass=89,
            Avantgarde=90,
            Gothic_Rock=91,
            Progresive_Rock=92,
            Psychedelic_Rock = 93,
            Symphonic_Rock = 94,
            Slow_Rock=95,
            Big_Band=96,
            Chorus=97,
            Easy_Listening=98,
            Acoustic=99,
            Humour=100,
            Speech=101,
            Chanson=102,
            Opera=103,
            Chamber_Music=104,
            Sonata=105,
            Symphony=106,
            Booty_Bass=107,
            Primus=108,
            Porn_Groove=109,
            Satire=110,
            Slow_Jam=111,
            Club=112,
            Tango=113,
            Samba=114,
            Folklore=115,
            Ballad=116,
            Power_Ballad=117,
            Rhythmic_Soul=118,
            Freestyle=119,
            Duet=120,
            PunkRock=121,
            Drum_Solo=122,
            Acapella=123,
            Euro_House=124,
            Dance_Hall=125,
            Goa_Trance=126,
            Drum_Bass=127,
            Club_House=128,
            Hardcore_Techno=129,
            Terror=130,
            Indie=131,
            Britpop=132,
            Afro_Punk=133,
            Polsk_Punk=134,
            Beat=135,
            Christian_Gangsta_Rap=136,
            Heavy_Metal=137,
            Black_Metal=138,
            Crossover=139,
            Contemporary_Christian=140,
            Christian_Rock=141,
            Merengue=142,
            Salsa=143,
            Thrash_Metal=144,
            Anime=145,
            Jpop=146,
            Synthpop=147,
            Abstract=148,
            Art_Rock=149,
            Baroque=150,
            Bhangra=151,
            Big_Beat=152,
            Breakbeat=153,
            Chillout=154,
            Downtempo=155,
            Dub=156,
            EBM=157,
            Eclectic=158,
            Electro=159,
            Electroclash=160,
            Emo=161,
            Experimental=162,
            Garage=163,
            Global = 164,
            IDM=165,
            Illbient=166,
            Industro_Goth=167,
            Jam_Band=168,
            Krautrock=169,
            Leftfield=170,
            Lounge=171,
            Math_Rock=172,
            New_Romantic=173,
            Nu_Breakz=174,
            Post_Punk=175,
            Post_Rock=176,
            Psytrance=177,
            Shoegaze=178,
            Space_Rock=179,
            Trop_Rock=180,
            World_Music=181,
            Neoclassical=182,
            Audiobook=183,
            Audio_Theatre=184,
            Neue_Deutsche_Welle=185,
            Podcast=186,
            Indie_Rock=187,
            G_Funk=188,
            Dubstep=189,
            Garage_Rock=190,
            Psybient=191
        }
    }
}

Programar con Archivos en el Formulario WinForms en C#

Escribir el siguiente código en el formulario "frmInfoMP3":

using System;
using System.Text;
using System.IO;
using System.Windows.Forms;

namespace Leer_Escribir_ID3_MP3
{
    public partial class frmInfoMP3 : Form
    {
        public frmInfoMP3()
        {
            InitializeComponent();
        }

        private void cargarGeneros(object sender, EventArgs e)
        {
            Type tipo = typeof(MP3ID3Tag.Generos);
            cboGenero.DataSource = Enum.GetNames(tipo);
            cboGenero.SelectedIndex = -1;
        }

        private void abrirArchivoMp3(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Title = "Abrir archivos mp3";
            ofd.Filter = "Archivos mp3|*.mp3";
            ofd.InitialDirectory = @"C:\Musica\The Best";
            if (ofd.ShowDialog().Equals(DialogResult.OK))
            {
                btnGrabar.Enabled = true;
                txtArchivoMp3.Text = ofd.FileName;
                leerInfoMP3();
            }
        }

        private void leerInfoMP3()
        {
            using (FileStream fs = File.OpenRead(txtArchivoMp3.Text))
            {
                if (fs.Length >= 128)
                {
                    MP3ID3Tag tag = new MP3ID3Tag();
                    fs.Seek(-128, SeekOrigin.End);
                    fs.Read(tag.Id, 0, tag.Id.Length);
                    fs.Read(tag.Titulo, 0, tag.Titulo.Length);
                    fs.Read(tag.Artista, 0, tag.Artista.Length);
                    fs.Read(tag.Album, 0, tag.Album.Length);
                    fs.Read(tag.Año, 0, tag.Año.Length);
                    fs.Read(tag.Comentario, 0, tag.Comentario.Length);
                    fs.Read(tag.Genero, 0, tag.Genero.Length);
                    string tagId = Encoding.Default.GetString(tag.Id);
                    if (tagId.Equals("TAG"))
                    {
                        txtTitulo.Text = Encoding.Default.GetString(tag.Titulo).Trim();
                        txtArtista.Text = Encoding.Default.GetString(tag.Artista).Trim();
                        txtAlbum.Text = Encoding.Default.GetString(tag.Album).Trim();
                        txtAño.Text = Encoding.Default.GetString(tag.Año);
                        byte[] comentario = new byte[28];
                        Buffer.BlockCopy(tag.Comentario, 0, comentario, 0, 28);
                        txtComentario.Text = Encoding.Default.GetString(comentario).Trim();
                        Type tipo = typeof(MP3ID3Tag.Generos);
                        byte n = (byte)tag.Genero[0];
                        string genero = Enum.GetName(tipo, n);
                        int pos = cboGenero.Items.IndexOf(genero);
                        if (pos > -1) cboGenero.SelectedIndex = pos;
                        if (tag.Comentario[28].Equals(0))
                        {
                            txtPista.Text = tag.Comentario[29].ToString();
                        }
                    }
                }
            }
        }

        private void escribirInfoMP3()
        {
            using (FileStream fs = File.OpenWrite(txtArchivoMp3.Text))
            {
                if (fs.Length >= 128)
                {
                    MP3ID3Tag tag = new MP3ID3Tag();
                    tag.Id = Encoding.Default.GetBytes("TAG");
                    tag.Titulo = Encoding.Default.GetBytes(txtTitulo.Text.PadRight(30, ' '));
                    tag.Artista = Encoding.Default.GetBytes(txtArtista.Text.PadRight(30, ' '));
                    tag.Album = Encoding.Default.GetBytes(txtAlbum.Text.PadRight(30, ' '));
                    tag.Año = Encoding.Default.GetBytes(txtAño.Text);
                    byte[] comentario = new byte[28];
                    comentario = Encoding.Default.GetBytes(txtComentario.Text.PadRight(28, ' '));
                    byte[] tienePista = new byte[] { 0 };
                    byte pista = byte.Parse(txtPista.Text);
                    byte[] numeroPista = new byte[] { pista };                  
                    Buffer.BlockCopy(comentario, 0, tag.Comentario, 0, 28);
                    Buffer.BlockCopy(tienePista, 0, tag.Comentario, 28, 1);
                    Buffer.BlockCopy(numeroPista, 0, tag.Comentario,29, 1);
                    Type tipo = typeof(MP3ID3Tag.Generos);
                    MP3ID3Tag.Generos genero = (MP3ID3Tag.Generos)
                    Enum.Parse(tipo, cboGenero.SelectedItem.ToString());
                    byte n = (byte)genero;
                    tag.Genero = new byte[] {n};
                    fs.Seek(-128, SeekOrigin.End);
                    fs.Write(tag.Id, 0, tag.Id.Length);
                    fs.Write(tag.Titulo, 0, tag.Titulo.Length);
                    fs.Write(tag.Artista, 0, tag.Artista.Length);
                    fs.Write(tag.Album, 0, tag.Album.Length);
                    fs.Write(tag.Año, 0, tag.Año.Length);
                    fs.Write(tag.Comentario, 0, tag.Comentario.Length);
                    fs.Write(tag.Genero, 0, tag.Genero.Length);
                    MessageBox.Show("ID Tag V1 del archivo mp3 fue cambiado");
                }
            }
        }

        private void grabarArchivoMP3(object sender, EventArgs e)
        {
            escribirInfoMP3();
        }
    }
}

Nota: La función "cargarGeneros" esta asociada al evento "Load" del formulario, la función "abrirArchivoMp3" esta asociada al evento "Click" del botón "btnAbrirMp3" y la función "grabarArchivoMP3" esta asociada al evento "Click" del botón "btnGrabar".

Probar la Aplicación Windows Forms

Grabar la aplicación y ejecutarla con F5. Se mostrará la siguiente ventana:


Nota: Ver como se ha llenado la lista con los géneros disponibles en la enumeración.

Clic al botón de la parte superior derecha y seleccionar un archivo MP3 en el diálogo de abrir, luego se mostrará la información de dicho archivo, similar a la siguiente figura:


Cambiar la información del archivo, por ejemplo el Album, cambiar el Genero, agregar un Comentario y luego "Grabar".


Cerrar la aplicación y volverla a ejecutar nuevamente para verificar si la información del archivo se guardó o también abrir el Winamp, reproducir la canción y pulsar Alt + 3 para ver la información del archivo y verificar que los cambios se han realizado satisfactoriamente.

Comentario Final

En este post hemos aprendido a leer y escribir la metadata de un archivo MP3 manejando los 128 últimos bytes del archivo usando el método "Seek" de la clase "FileStream" para ubicarnos en los últimos 128 bytes y a partir de esa posición usar "Read" para leer y "Write" para escribir.

Espero que les guste este primer post y tratare de que sean mas seguidos, ya que es lo que mas interesa a los visitantes del Blog.

Descarga como rar
Demo28_Leer_Escribir_ID3_MP3

Descarga sin extension (luego renombrar a rar y descomprimir)
Leer_Escribir_ID3_MP3