Maison > développement back-end > tutoriel php > Structures de données hautes performances et méthodes d'implémentation sous-jacentes à PHP

Structures de données hautes performances et méthodes d'implémentation sous-jacentes à PHP

王林
Libérer: 2023-11-08 19:44:01
original
1142 Les gens l'ont consulté

Structures de données hautes performances et méthodes dimplémentation sous-jacentes à PHP

La structure de données hautes performances et les méthodes d'implémentation de PHP nécessitent des exemples de code spécifiques

Avec le développement continu des applications Internet, PHP est devenu un langage de script côté serveur largement utilisé. Cependant, dans les applications Web à grande échelle, les problèmes de performances de PHP sont devenus un problème qui ne peut être ignoré. De nombreux grands sites Web ont connu des goulots d'étranglement et des pannes de système.

Afin d'améliorer les performances de PHP, nous devons comprendre la structure de données hautes performances et les méthodes d'implémentation sous-jacentes à PHP. Cet article présentera plusieurs structures de données PHP hautes performances et leurs méthodes de mise en œuvre, et fournira des exemples de code correspondants pour aider les lecteurs à comprendre en profondeur l'optimisation des performances PHP.

  1. Arrays

En PHP, les tableaux sont l'une des structures de données les plus couramment utilisées. Cependant, l'implémentation de tableaux de PHP utilise une table de hachage, ce qui entraînera une certaine surcharge de performances, en particulier lors de l'itération d'une grande quantité de données.

Afin d'améliorer les performances des tableaux de PHP, nous pouvons utiliser des extensions du langage C pour y parvenir.

Ce qui suit est un exemple d'extension PHP simple, qui implémente une table de hachage hautes performances qui peut être utilisée pour stocker de grandes quantités de données et prend en charge le stockage et l'accès à divers types de données.

typedef struct {
    zend_ulong h;
    zval data;
} hashtable_entry;

typedef struct {
    hashtable_entry *table;
    zend_ulong num_entries;
    zend_ulong max_entries;
    zend_ulong rehash_pos;
    zend_ulong rehash_size;
} hashtable;

typedef struct {
    zend_object std;
    hashtable *ht;
} hash_table_object;

static zend_object *hash_table_object_new(zend_class_entry *class_type)
{
    hash_table_object *intern = 
        (hash_table_object *)ecalloc(1, sizeof(hash_table_object));
    zend_object_std_init(&intern->std, class_type);
    object_properties_init(&intern->std, class_type);
    intern->std.handlers = &hash_table_object_handlers;
    intern->ht = 
        (hashtable *)emalloc(sizeof(hashtable));
    return &intern->std;
}

static void hash_table_object_free(zend_object *object)
{
    hash_table_object *intern = 
        hash_table_object_from_obj(object);
    if (intern->ht != NULL) {
        zend_ulong i;
        for (i = 0; i < intern->ht->max_entries; i++) {
            zval_dtor(
                &intern->ht->table[i].data
            );
        }
        efree(intern->ht->table);
        efree(intern->ht);
    }
    zend_object_std_dtor(object);
}

static void hash_table_put(hash_table_object *intern, 
                           zval *key, 
                           zval *value)
{
    zend_ulong idx;
    zend_string *str_key;
    if (Z_TYPE_P(key) == IS_STRING) {
        str_key = Z_STR_P(key);
        idx = zend_inline_hash_func(
            str_key->val, str_key->len
        ) % intern->ht->max_entries;
    } else if (Z_TYPE_P(key) == IS_LONG) {
        idx = Z_LVAL_P(key) % intern->ht->max_entries;
    } else if (Z_TYPE_P(key) == IS_DOUBLE) {
        idx = zend_dval_to_lval(Z_DVAL_P(key)) % intern->ht->max_entries;
    } else if (Z_TYPE_P(key) == IS_TRUE) {
        idx = 1 % intern->ht->max_entries;
    } else {
        idx = 0;
    }
    if (Z_TYPE(intern->ht->table[idx].data) != IS_NULL) {
        zval_dtor(
            &intern->ht->table[idx].data
        );
    }
    intern->ht->table[idx].h = idx;
    ZVAL_COPY_VALUE(
        &intern->ht->table[idx].data, value
    );
}

static zval *hash_table_get(hash_table_object *intern, 
                             zval *key)
{
    zend_ulong idx;
    zend_string *str_key;
    if (Z_TYPE_P(key) == IS_STRING) {
        str_key = Z_STR_P(key);
        idx = zend_inline_hash_func(
            str_key->val, str_key->len
        ) % intern->ht->max_entries;
    } else if (Z_TYPE_P(key) == IS_LONG) {
        idx = Z_LVAL_P(key) % intern->ht->max_entries;
    } else if (Z_TYPE_P(key) == IS_DOUBLE) {
        idx = zend_dval_to_lval(Z_DVAL_P(key)) % intern->ht->max_entries;
    } else if (Z_TYPE_P(key) == IS_TRUE) {
        idx = 1 % intern->ht->max_entries;
    } else {
        idx = 0;
    }
    if (Z_TYPE(intern->ht->table[idx].data) == IS_NULL) {
        return NULL;
    } else {
        return &intern->ht->table[idx].data;
    }
}

static zend_class_entry *hash_table_class_entry;

static zend_function_entry hash_table_methods[] = {
    PHP_ME(HashTable, put, arginfo_hashtable_put, ZEND_ACC_PUBLIC)
    PHP_ME(HashTable, get, arginfo_hashtable_get, ZEND_ACC_PUBLIC)
    PHP_FE_END
};

static zend_object_handlers hash_table_object_handlers;

static void hash_table_object_init(zend_class_entry *class_type)
{
    hash_table_object_handlers = 
        *zend_get_std_object_handlers();
    hash_table_object_handlers.offset = 
        XtOffsetOf(hash_table_object, std);
    hash_table_object_handlers.free_obj = 
        hash_table_object_free;
    hash_table_object_handlers.clone_obj = 
        zend_objects_clone_obj;
}

PHP_MINIT_FUNCTION(hash_table)
{
    zend_class_entry ce;
    INIT_CLASS_ENTRY(ce, "HashTable", hash_table_methods);
    hash_table_class_entry = zend_register_internal_class(&ce);
    hash_table_class_entry->create_object =
        hash_table_object_new;
    hash_table_object_init(
        hash_table_class_entry
    );
    return SUCCESS;
}
Copier après la connexion

En utilisant les extensions ci-dessus, les performances des tableaux PHP peuvent être considérablement améliorées, particulièrement adaptées au traitement de données à grande échelle.

  1. Heap

Heap est une structure de données couramment utilisée qui peut être utilisée pour la file d'attente prioritaire, le tri et d'autres opérations. Afin d'améliorer les performances de PHP, nous pouvons utiliser des extensions du langage C pour implémenter des structures de données en tas.

Ce qui suit est un exemple d'extension PHP simple, qui implémente un tas minimum et peut être utilisé pour le tri, la recherche et d'autres opérations.

typedef struct {
    zend_ulong size;
    zend_ulong capacity;
    zval *data;
} min_heap;

static min_heap *min_heap_new()
{
    min_heap *heap = emalloc(sizeof(min_heap));
    heap->size = 0;
    heap->capacity = 4;
    heap->data = emalloc(sizeof(zval) * heap->capacity);
    return heap;
}

static void min_heap_free(min_heap *heap)
{
    zend_ulong i;
    for (i = 0; i < heap->size; i++) {
        zval_dtor(&heap->data[i]);
    }
    efree(heap->data);
    efree(heap);
}

static void min_heap_push(min_heap *heap, zval *value)
{
    if (heap->size + 1 > heap->capacity) {
        heap->capacity *= 2;
        heap->data = 
            erealloc(heap->data, sizeof(zval) * heap->capacity);
    }
    zend_ulong hole = ++heap->size;
    while (hole > 1 && 
           zend_is_smaller(
               value, &heap->data[hole / 2]
           )) {
        ZVAL_COPY(
            &heap->data[hole], &heap->data[hole / 2]
        );
        hole /= 2;
    }
    ZVAL_COPY(
        &heap->data[hole], value
    );
}

static void min_heap_pop(min_heap *heap)
{
    zend_ulong hole = 1;
    zend_ulong child = 2;
    zval tmp;
    ZVAL_NULL(&tmp);
    zval_dtor(
        &heap->data[1]
    );
    heap->data[1] = heap->data[heap->size--];
    while (child <= heap->size) {
        if (child < heap->size && 
            zend_is_smaller(&heap->data[child + 1], &heap->data[child])) {
            child++;
        }
        if (zend_is_smaller(&heap->data[child], &heap->data[hole])) {
            ZVAL_COPY(
                &tmp, &heap->data[hole]
            );
            ZVAL_COPY(
                &heap->data[hole], &heap->data[child]
            );
            ZVAL_COPY(
                &heap->data[child], &tmp
            );
        } else {
            break;
        }
        hole = child;
        child *= 2;
    }
}

static zval *min_heap_top(min_heap *heap)
{
    if (heap->size > 0) {
        return &heap->data[1];
    } else {
        return NULL;
    }
}

static zend_class_entry *min_heap_class_entry;

static zend_function_entry min_heap_methods[] = {
    PHP_ME(MinHeap, push, arginfo_min_heap_push, ZEND_ACC_PUBLIC)
    PHP_ME(MinHeap, pop, arginfo_min_heap_pop, ZEND_ACC_PUBLIC)
    PHP_ME(MinHeap, top, arginfo_min_heap_top, ZEND_ACC_PUBLIC)
    PHP_FE_END
};

static zend_object_handlers min_heap_object_handlers;

static void min_heap_object_init(zend_class_entry *class_type)
{
    min_heap_object_handlers = 
        *zend_get_std_object_handlers();
    min_heap_object_handlers.offset = 
        XtOffsetOf(min_heap_object, std);
    min_heap_object_handlers.free_obj = 
        min_heap_object_free;
    min_heap_object_handlers.clone_obj = 
        zend_objects_clone_obj;
}

static zend_object *min_heap_object_new(zend_class_entry *class_type)
{
    min_heap_object *intern = 
        (min_heap_object *)ecalloc(1, sizeof(min_heap_object));
    zend_object_std_init(&intern->std, class_type);
    object_properties_init(&intern->std, class_type);
    intern->std.handlers = &min_heap_object_handlers;
    intern->heap = 
        min_heap_new();
    return &intern->std;
}

static void min_heap_object_free(zend_object *object)
{
    min_heap_object *intern = 
        min_heap_object_from_obj(object);
    if (intern->heap != NULL) {
        min_heap_free(intern->heap);
    }
    zend_object_std_dtor(object);
}

PHP_MINIT_FUNCTION(min_heap)
{
    zend_class_entry ce;
    INIT_CLASS_ENTRY(ce, "MinHeap", min_heap_methods);
    min_heap_class_entry = zend_register_internal_class(&ce);
    min_heap_class_entry->create_object =
        min_heap_object_new;
    min_heap_object_init(
        min_heap_class_entry
    );
    return SUCCESS;
}
Copier après la connexion

En utilisant les extensions ci-dessus, vous pouvez facilement implémenter la structure de données du tas en PHP et améliorer les performances du tri, de la recherche et d'autres opérations PHP.

  1. Queue

La file d'attente en PHP est une structure de données courante qui peut être utilisée dans des scénarios d'application tels que la gestion de tâches multithread. Afin d'améliorer les performances de PHP, nous pouvons utiliser des extensions du langage C pour implémenter des structures de données de file d'attente.

Ce qui suit est un exemple d'extension PHP simple, qui implémente une file d'attente hautes performances et peut être utilisée dans des scénarios d'application tels que le traitement de tâches multithread.

typedef struct {
    zend_ulong head;
    zend_ulong tail;
    zend_ulong size;
    zend_ulong capacity;
    zval *data;
} queue;

static queue *queue_new()
{
    queue *q = emalloc(sizeof(queue));
    q->head = 0;
    q->tail = 0;
    q->size = 0;
    q->capacity = 4;
    q->data = emalloc(sizeof(zval) * q->capacity);
    return q;
}

static void queue_free(queue *q)
{
    zend_ulong i;
    for (i = q->head; i != q->tail; i = (i + 1) % q->capacity) {
        zval_dtor(&q->data[i]);
    }
    efree(q->data);
    efree(q);
}

static void queue_push(queue *q, zval *val)
{
    if (q->size >= q->capacity) {
        zend_ulong new_capacity = q->capacity * 2;
        zval *new_data = emalloc(sizeof(zval) * new_capacity);
        zend_ulong i;
        for (i = q->head; i != q->tail; i = (i + 1) % q->capacity) {
            ZVAL_COPY(&new_data[i], &q->data[i]);
        }
        efree(q->data);
        q->data = new_data;
        q->capacity = new_capacity;
        q->head = 0;
        q->tail = q->size;
    }
    ZVAL_COPY(&q->data[q->tail], val);
    q->tail = (q->tail + 1) % q->capacity;
    q->size++;
}

static void queue_pop(queue *q)
{
    if (q->size > 0) {
        zval_dtor(&q->data[q->head]);
        q->head = (q->head + 1) % q->capacity;
        q->size--;
    }
}

static zval *queue_front(queue *q)
{
    if (q->size > 0) {
        return &q->data[q->head];
    } else {
        return NULL;
    }
}

static zend_class_entry *queue_class_entry;

static zend_function_entry queue_methods[] = {
    PHP_ME(Queue, push, arginfo_queue_push, ZEND_ACC_PUBLIC)
    PHP_ME(Queue, pop, arginfo_queue_pop, ZEND_ACC_PUBLIC)
    PHP_ME(Queue, front, arginfo_queue_front, ZEND_ACC_PUBLIC)
    PHP_FE_END
};

static zend_object_handlers queue_object_handlers;

static void queue_object_init(zend_class_entry *class_type)
{
    queue_object_handlers = 
        *zend_get_std_object_handlers();
    queue_object_handlers.offset = 
        XtOffsetOf(queue_object, std);
    queue_object_handlers.free_obj = 
        queue_object_free;
    queue_object_handlers.clone_obj = 
        zend_objects_clone_obj;
}

static zend_object *queue_object_new(zend_class_entry *class_type)
{
    queue_object *intern = 
        (queue_object *)ecalloc(1, sizeof(queue_object));
    zend_object_std_init(&intern->std, class_type);
    object_properties_init(&intern->std, class_type);
    intern->std.handlers = &queue_object_handlers;
    intern->q = 
        queue_new();
    return &intern->std;
}

static void queue_object_free(zend_object *object)
{
    queue_object *intern = 
        queue_object_from_obj(object);
    if (intern->q != NULL) {
        queue_free(intern->q);
    }
    zend_object_std_dtor(object);
}

PHP_MINIT_FUNCTION(queue)
{
    zend_class_entry ce;
    INIT_CLASS_ENTRY(ce, "Queue", queue_methods);
    queue_class_entry = zend_register_internal_class(&ce);
    queue_class_entry->create_object =
        queue_object_new;
    queue_object_init(
        queue_class_entry
    );
    return SUCCESS;
}
Copier après la connexion

En utilisant les extensions ci-dessus, vous pouvez facilement implémenter la structure de données de file d'attente en PHP et améliorer les performances du traitement des tâches multithread PHP et d'autres scénarios d'application.

Résumé

Après l'introduction ci-dessus, nous avons découvert la structure de données hautes performances et sa méthode d'implémentation sous-jacente à PHP, et avons fourni des exemples de code correspondants. En utilisant des extensions pour implémenter des structures de données hautes performances, les performances de PHP peuvent être considérablement améliorées, en particulier lors du traitement de grandes quantités de données et de tâches multithread, cela peut améliorer considérablement les performances du système.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal