estructura tipo y la prueba de comparación de rendimiento - Ejemplo paquete de latido para encapsular la red

1. Antecedentes

artículos continuos en la estructura del lenguaje C # laico - paquetes de latidos del paquete Ethernet, por ejemplo , el uso de la estructura pobre rendimiento, sino que también explica por qué. Este artículo describe en detalle las ventajas y desventajas en la clase para encapsular la red de paquetes latido del corazón, los resultados mejoraron considerablemente el rendimiento analítico.

2. latido paquetes encapsulados Ethernet ventajas de clase y desventajas

2.1 Ventajas

  • nuevo byte directa [], una matriz de bytes que es una clase de instancia directa, y luego escribir el método de inicialización o constructor pasó directamente en la asignación de copia caché;
  • No es necesario el boxeo y unboxing;
  • Categoría es un tipo de referencia, un valor sin copiar la estructura de la imagen, la capa inferior es puntero directamente inteligente;
  • punteros inteligentes a la misma pieza de la memoria, excepto la memoria;
  • Puedo escribir un montón de método conveniente en clase, que es, piedra angular orientado a dominio orientado a objetos para la futura expansión fácil;

2.2 Desventajas

  • Presencia pila, pila algo menor que el rendimiento de lectura (el PC ahora calcular rápidamente la velocidad, sustancialmente despreciable);
  • Aunque la clase también pertenecen a un recurso gestionado de GC, GC, pero cuando la recuperación automática no puede controlar, es necesario implementar la interfaz IDisposable, salir corriendo de la clase, la clase se libera manualmente la acción;

Cómo utilizar la clase de potencia real, utilizamos los datos de prueba para tomar la palabra, vamos a poner detrás de la actuación de datos comparativos y pruebas de estructura.

Paquete de Encapsulación de latido del corazón basada en la red 3.

Aquí están todos llamados convirtió en una matriz de bytes, incluyendo public byte [] Tipo = new byte [1]; porque si es de tipo byte de tipo, no sé cómo liberar este tipo de valor, el miedo de causar problemas tales como pérdidas de memoria ese momento. A continuación, la función constructora para copiar el buffer buf cada clase de propiedad, es así de simple.

    public class TcpHeartPacketClass: BaseDisposable
    {
        private bool _disposed; //表示是否已经被回收
        public TcpHeartPacketClass(byte[] buf)
        {
            Buffer.BlockCopy(buf, 0, head, 0, 4);
            type[0] = buf[4];
            Buffer.BlockCopy(buf, 4, length, 0, 2);
            Buffer.BlockCopy(buf, 6, Mac, 0, 6);
            Buffer.BlockCopy(buf, 12, data, 0, 104);
            Buffer.BlockCopy(buf, 116, tail, 0, 4);
        }
        protected override void Dispose(bool disposing)
        {
            if (!_disposed) //如果还没有被回收
            {
                if (disposing) //如果需要回收一些托管资源
                {
                    //TODO:回收托管资源,调用IDisposable的Dispose()方法就可以
                    
                }
                //TODO:回收非托管资源,把之设置为null,等待CLR调用析构函数的时候回收
                head = null;
                type = null;
                length = null;
                Mac = null;
                data = null;
                tail = null;

                _disposed = true;

            }
            base.Dispose(disposing);//再调用父类的垃圾回收逻辑
        }

        public byte[] head=new byte[4];

        public byte[] type=new byte[1];

        public byte[] length = new byte[2];

        public byte[] Mac = new byte[6];

        public byte[] data = new byte[104];//数据体

        public byte[] tail = new byte[4];
    }  

4. Implementar interfaz IDisposable

Agotado después de clase, a tomar la iniciativa para liberar la clase, la liberación que encapsula un BaseDisposable clase base. Consulte las notas de código, hay no entienden pueden hacer preguntas en la sección de comentarios, voy a responder en detalle.

    public class BaseDisposable : IDisposable
    {
        ~BaseDisposable()
        {
            //垃圾回收器将调用该方法,因此参数需要为false。
            Dispose(false);
        }

        /// <summary>
        /// 是否已经调用了 Dispose(bool disposing)方法。
        ///     应该定义成 private 的,这样可以使基类和子类互不影响。
        /// </summary>
        private bool disposed = false;

        /// <summary>
        /// 所有回收工作都由该方法完成。
        ///     子类应重写(override)该方法。
        /// </summary>
        /// <param name="disposing"></param>
        protected virtual void Dispose(bool disposing)
        {
            // 避免重复调用 Dispose 。
            if (!disposed) return;

            // 适应多线程环境,避免产生线程错误。
            lock (this)
            {
                if (disposing)
                {
                    // ------------------------------------------------
                    // 在此处写释放托管资源的代码
                    // (1) 有 Dispose() 方法的,调用其 Dispose() 方法。
                    // (2) 没有 Dispose() 方法的,将其设为 null。
                    // 例如:
                    //     xxDataTable.Dispose();
                    //     xxDataAdapter.Dispose();
                    //     xxString = null;
                    // ------------------------------------------------
                }

                // ------------------------------------------------
                // 在此处写释放非托管资源
                // 例如:
                //     文件句柄等
                // ------------------------------------------------
                disposed = true;
            }
        }

        /// <summary>
        /// 该方法由程序调用,在调用该方法之后对象将被终结。
        ///     该方法定义在IDisposable接口中。
        /// </summary>
        public void Dispose()
        {
            //因为是由程序调用该方法的,因此参数为true。
            Dispose(true);
            //因为我们不希望垃圾回收器再次终结对象,因此需要从终结列表中去除该对象。
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// 调用 Dispose() 方法,回收资源。
        /// </summary>
        public void Close()
        {
            Dispose();
        }
    }

Las llamadas de la capa de aplicación

    DateTime packetClassStart = DateTime.Now;

    TcpHeartPacketClass tcpHeartPacketClass = neTcpHeartPacketClass(ReceviveBuff);

    DateTime packetClassEnd = DateTime.Now;
    TimeSpan toClassTs = packetClassEnd.Subtra(packetClassStart);
    try
    {
    tcpHeartPacketClass.head[0] = 0x11;
    
    LoggerHelper.Info("类中的包头:" + BitConverteToString(tcpHeartPacketClass.head));
    Console.WriteLine("类中的包头:{0}", BitConverteToString(tcpHeartPacketClass.head));

    LoggerHelper.Info("类中的包类型:" tcpHeartPacketClass.type.ToString());
    Console.WriteLine("类中的包类型:{0}"tcpHeartPacketClass.type.ToString());

    LoggerHelper.Info("类中的包长度:" + BitConverteToString(tcpHeartPacketClass.length));
    Console.WriteLine("类中的包长度:{0}", BitConverteToString(tcpHeartPacketClass.length));

    LoggerHelper.Info("类中的MAC地址:" + BitConverteToString(tcpHeartPacketClass.Mac));
    Console.WriteLine("类中的MAC地址:{0}", BitConverteToString(tcpHeartPacketClass.Mac));

    LoggerHelper.Info("类中的注册包内容:" + BitConverteToString(tcpHeartPacketClass.data));
    Console.WriteLine("类中的注册包内容:{0}"BitConverter.ToString(tcpHeartPacketClass.data));

    LoggerHelper.Info("类中的包尾:" + BitConverteToString(tcpHeartPacketClass.tail));
    Console.WriteLine("类中的包尾:{0}", BitConverteToString(tcpHeartPacketClass.tail));

    Console.WriteLine("字节数组类中分割总共花费{0}ms\n"toClassTs.TotalMilliseconds);
    }
    finally
    {
        IDisposable disposable = tcpHeartPacketClass as IDisposable;
        if (disposable != null)
            disposable.Dispose();
    }

6.Gestione () método en el ensayo de fuerza

Después de Ty ... finalmente bloquear la ejecución del método Dispose (), ir a una clase de asignación de propiedad, nos fijamos en si el error, si el error asignado al objeto nulo es demostrar la liberación exitosa.

    finally
    {
        IDisposable disposable = tcpHeartPacketClass        IDisposable;
        if (disposable != null)
            disposable.Dispose();
    }
    tcpHeartPacketClass.head[0] = 0x12;

El error de seguimiento, lo que se traduce lo que significa que hay referencias a objetos no correspondiente un ejemplo, que tenemos que ser liberado.

7. Prueba de Rendimiento comparativo

Puede ser visto por la figura, la clase anterior es microsegundo analizada, y artículos estructura laico C # - latido del corazón paquetes encapsulados Ethernet ejemplo de configuración de nivel analítico de varias decenas de microsegundos, la diferencia de casi 5 10 veces el rendimiento.

Por lo tanto, en este escenario, el uso de una clase de paquetes de latido del corazón para encapsular la estructura de la red es más razonable que el paquete.

8. En resumen, el C #, el efecto principal de las dos estructuras siguientes:

  • La longitud de datos es muy corto, el nuevo 16 bytes configuración de tipo, subtipo y las estructuras en el cuerpo debe ser un tipo de valor, de lo contrario no significa, que están diseñados para dar cabida a una lectura eficiente en la pila;
  • Para la compatibilidad con C en algunas bibliotecas en C ++;
    evitar lo anterior dos puntos, creo que en C # para desarrollar nuevas aplicaciones, puede ser reemplazado por completo con una estructura de clases (sólo en nombre de vista personal).

Aviso: Este artículo es un artículo blogger original, siga el CC 4.0 BY-SA acuerdo de derecho de autor, reproduce, por favor adjuntar el enlace de la fuente original y esta declaración.

Este enlace: https://www.cnblogs.com/JerryMouseLi/p/12610332.html

Supongo que te gusta

Origin www.cnblogs.com/JerryMouseLi/p/12610332.html
Recomendado
Clasificación