Nuevos cambios en la asignación de memoria de clase de cadena de Qt6: aumento de potencia de 16

qt proporciona una clase de cadena QString más potente, rica y práctica que la cadena estándar de c++. Sus 22 funciones principales se han analizado una por una antes. Si está interesado, puede ir al siguiente enlace para ver. Este artículo principalmente se centra en el análisis de qt en La optimización realizada en la clase de cadena se encuentra principalmente en dos aspectos, el intercambio implícito y la estrategia de asignación de memoria .

9-Qt6 QString y QChar_qchar qstring_Yan Youjinyiwuqiong's blog - CSDN blog https://yanchenyu.blog.csdn.net/article/details/119640571  También puede prestar atención a los documentos oficiales:

Clase QString | Qt Núcleo 6.5.0 https://doc.qt.io/qt-6/qstring.html#detalles

1. Uso compartido implícito

La clase compartida consta de un bloque de datos compartidos y un contador que apunta a este bloque. Cuando se crea un objeto compartido, el valor del contador de este bloque se establecerá en 1, y cuando un nuevo objeto apunte a la base de datos compartida, su el contador será + 1. Cuando el objeto no apunte a este bloque de memoria, el contador disminuirá, cuando el contador sea 0, el bloque compartido será eliminado.

En pocas palabras, cuando dos objetos comparten los mismos datos, si los datos no cambian, los datos no se copiarán (solo una copia superficial), y cuando los datos cambien, los datos se copiarán, es decir, se hará una copia profunda. ser realizado.

Copia superficial , solo haga dos cosas, establezca un puntero en el bloque de datos compartido y luego modifique el valor del recuento de referencia;

Deep copy , que genera una copia completa de un objeto;

Obviamente, la copia profunda consumirá más recursos, como CPU, memoria, etc., mientras que la copia superficial es solo una referencia de puntero y cuenta, y la eficiencia será muy alta.

La tecnología de uso compartido implícito de Qt es combinar copia superficial y copia profunda para mejorar la eficiencia operativa y reducir el uso de recursos. El siguiente código explica:

QString str1="china";
    qDebug()<<"&str1="<<str1.data_ptr();
    QString str2=str1;
    qDebug()<<"&str2="<<str2.data_ptr();
    str2.at(0);
    qDebug()<<"&str2.at(0)="<<str2.data_ptr();
    str2[0]='a';
    qDebug()<<"&str2="<<str2.data_ptr();
    qDebug()<<"&str1="<<str1.data_ptr();

Cuando str2=str1  por primera vez , puede ver que la dirección no ha cambiado, lo que indica que solo se ha producido una copia superficial y apuntan al mismo contenido.

Inmediatamente después de llamar a para acceder al primer elemento de str2, la dirección permanece sin cambios;

Finalmente, después de modificar el primer elemento de str2, la dirección de str2 cambia, porque se ha realizado una copia profunda, es decir, la estructura de datos a la que apunta ya es un área nueva, y la dirección del puntero también cambia en consecuencia, que es decir, la nueva dirección es un nuevo valor, pero la dirección de str1 no ha cambiado en este momento, es decir, la dirección inicial y el valor inicial.

Lo anterior demuestra plenamente que qt es una combinación de copia profunda y copia superficial para minimizar el uso de recursos. Es esta pequeña optimización inconsciente la que se acumula para mejorar la eficiencia.

2. Estrategia de asignación de memoria

Contenedores | Qt Core 6.5.0 https://doc.qt.io/qt-6/containers.html

 Luego, también uso el código para mostrar que la asignación de memoria se describe en el documento, que puede ser 8, 24, 56, 120...;

 //El documento oficial qt6 anterior es como se describe anteriormente:

A través de experimentos, se puede concluir que qt6 ha sufrido nuevos cambios en la memoria, y de hecho la memoria está aumentando en la potencia de 16, en lugar de la llamada asignación de las tres situaciones que se han discutido en qt5. (A partir del 23 de mayo, el nuevo libro conocido como el llamado qt6 aún continúa promoviendo los siguientes tres métodos de distribución).

La descripción de qt5 dice que hay tres situaciones:

  • A QString se le asignan 4 caracteres a la vez hasta que el tamaño alcanza los 20 caracteres;
  • Cuando el tamaño está entre 20 y 4084 caracteres, el bloque de memoria asignado cada vez es del tamaño del espacio actual (es decir, la velocidad actual se duplica). Para ser precisos, asigne la siguiente potencia entera de 2 menos 12 (es decir, 2^n-12) . Esto se debe a que en algunos asignadores de memoria, se asignan previamente algunos bytes de espacio para la sobrecarga de memoria de contabilidad (la contabilidad se usa al implementar la asignación de memoria, para una comprensión más profunda, puede ir a la administración de memoria interna para ver "otras implementaciones de malloc " ), por lo que el rendimiento es menor cuando se asignan tamaños que son potencias enteras de 2.
  • A partir de 4084 caracteres, se asignan 2048 caracteres cada vez (4096 bytes, o 4 KB, que es exactamente igual al tamaño de página de un sistema informático con espacio de direcciones lógicas de 32 bits), porque los sistemas operativos modernos no reasignan un búfer. se copia ( implícitamente compartido ), y las páginas físicas simplemente se reordenan, de hecho, solo se necesita copiar los datos de la primera y la última página.

 En resumen, ya sea que qt adopte los últimos tres métodos de asignación o el método actual de asignación de energía número 16, qt utiliza estrategias de asignación de memoria dinámica e intercambio implícito para optimizar la ocupación de recursos y mejorar la eficiencia.

Supongo que te gusta

Origin blog.csdn.net/yanchenyu365/article/details/130705041
Recomendado
Clasificación