Struktur data dan kaedah pelaksanaan berprestasi tinggi PHP memerlukan contoh kod khusus
Dengan pembangunan aplikasi Internet yang berterusan, PHP telah menjadi bahasa skrip bahagian pelayan yang digunakan secara meluas. Walau bagaimanapun, dalam aplikasi web berskala besar, isu prestasi PHP telah menjadi masalah yang tidak boleh diabaikan Banyak tapak web besar telah mengalami kesesakan prestasi dan ranap sistem.
Untuk meningkatkan prestasi PHP, kita perlu memahami struktur data berprestasi tinggi dan kaedah pelaksanaan yang mendasari PHP. Artikel ini akan memperkenalkan beberapa struktur data berprestasi tinggi PHP dan kaedah pelaksanaannya, dan menyediakan contoh kod yang sepadan untuk membantu pembaca memahami secara mendalam pengoptimuman prestasi PHP.
Dalam PHP, tatasusunan ialah salah satu struktur data yang paling biasa digunakan. Walau bagaimanapun, pelaksanaan tatasusunan PHP menggunakan jadual cincang, yang akan membawa beberapa overhed prestasi, terutamanya apabila lelaran sejumlah besar data.
Untuk meningkatkan prestasi tatasusunan PHP, kami boleh menggunakan sambungan bahasa C untuk mencapainya.
Berikut ialah contoh sambungan PHP mudah, yang melaksanakan jadual cincang berprestasi tinggi yang boleh digunakan untuk menyimpan sejumlah besar data dan menyokong penyimpanan dan akses pelbagai jenis data.
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; }
Menggunakan sambungan di atas, prestasi tatasusunan PHP boleh dipertingkatkan dengan sangat baik, terutamanya sesuai untuk memproses data berskala besar.
Heap ialah struktur data yang biasa digunakan yang boleh digunakan untuk baris gilir keutamaan, pengisihan dan operasi lain. Untuk meningkatkan prestasi PHP, kami boleh menggunakan sambungan bahasa C untuk melaksanakan struktur data timbunan.
Berikut ialah contoh sambungan PHP mudah, yang melaksanakan timbunan minimum dan boleh digunakan untuk mengisih, mencari dan operasi lain.
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; }
Menggunakan sambungan di atas, anda boleh melaksanakan struktur data timbunan dalam PHP dengan mudah dan meningkatkan prestasi pengisihan PHP, carian dan operasi lain.
Barisan dalam PHP ialah struktur data biasa yang boleh digunakan dalam senario aplikasi seperti pengurusan tugasan berbilang benang. Untuk meningkatkan prestasi PHP, kami boleh menggunakan sambungan bahasa C untuk melaksanakan struktur data baris gilir.
Berikut ialah contoh sambungan PHP mudah, yang melaksanakan baris gilir berprestasi tinggi dan boleh digunakan dalam senario aplikasi seperti pemprosesan tugas berbilang benang.
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; }
Menggunakan sambungan di atas, anda boleh melaksanakan struktur data baris gilir dengan mudah dalam PHP dan meningkatkan prestasi pemprosesan tugas berbilang benang PHP dan senario aplikasi lain.
Ringkasan
Selepas pengenalan di atas, kami telah mempelajari tentang struktur data berprestasi tinggi yang mendasari PHP dan kaedah pelaksanaannya, dan menyediakan contoh kod yang sepadan. Dengan menggunakan sambungan untuk melaksanakan struktur data berprestasi tinggi, prestasi PHP boleh dipertingkatkan dengan ketara, terutamanya apabila memproses sejumlah besar data dan tugas berbilang benang, ia boleh meningkatkan prestasi sistem dengan ketara.
Atas ialah kandungan terperinci Struktur data berprestasi tinggi dan kaedah pelaksanaan yang mendasari PHP. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!