この記事では主に、PHP 配列の低メモリ使用率と弱い型の詳細な解釈を紹介します。一定の参考値があるので、興味のある方は参考にしてください。
この 2 日間のタスクは予定より早く完了しました。落ち着いて PHP を深く学ぶために一息入れることができます。実は、もともとPHPのパフォーマンス最適化について学びたかったのですが、ネット上の「PHPの配列メモリ使用率は低い。C言語で100MBのメモリ配列はPHPで1G必要。」という文章に衝撃を受けました。 PHP は本当に多くのメモリを消費しますか?そこで私はこの機会を利用して、PHP のデータ型の実装について学びました。
まずテストをしてみましょう:
<?php echo memory_get_usage() , '<br>'; $start = memory_get_usage(); $a = Array(); for ($i=0; $i<1000; $i++) { $a[$i] = $i + $i; } $end = memory_get_usage(); echo memory_get_usage() , '<br>'; echo 'argv:', ($end - $start)/1000 ,'bytes' , '<br>';
結果:
353352
437848
argv: 84.416bytes
1000 要素の整数配列はメモリを消費します (4 37848 - 353352) バイト、約 82KB 、つまり各要素は 84 バイトのメモリを占有します。 C 言語では、int は 4 バイトを占有し、全体で 20 倍の違いがあります。
しかし、インターネットでは、memory_get_usage() によって返される結果はすべての配列占有ではなく、PHP 自体の構造も含まれていると言われています。そのため、別の方法を試し、PHP 組み込み関数を使用して配列を生成してください。
<?php $start = memory_get_usage(); $a = array_fill(0, 10000, 1); $end = memory_get_usage(); //10k elements array; echo 'argv:', ($end - $start )/10000,'byte' , '<br>';
typedef struct _zval_struct zval; struct _zval_struct { /* Variable information */ zvalue_value value; /* The value 1 12字节(32位机是12,64位机需要8+4+4=16) */ zend_uint refcount__gc; /* The number of references to this value (for GC) 4字节 */ zend_uchar type; /* The active type 1字节*/ zend_uchar is_ref__gc; /* Whether this value is a reference (&) 1字节*/ };
typedef union _zvalue_value { long lval; /* long value */ double dval; /* double value */ struct { /* string value */ char *val; int len; } str; HashTable *ht; /* hash table value */ zend_object_value obj; /*object value */ } zvalue_value;
typedef struct _hashtable { uint nTableSize; //表长度,并非元素个数 uint nTableMask;//表的掩码,始终等于nTableSize-1 uint nNumOfElements;//存储的元素个数 ulong nNextFreeElement;//指向下一个空的元素位置 Bucket *pInternalPointer;//foreach循环时,用来记录当前遍历到的元素位置 Bucket *pListHead; Bucket *pListTail; Bucket **arBuckets;//存储的元素数组 dtor_func_t pDestructor;//析构函数 zend_bool persistent;//是否持久保存。从这可以发现,PHP数组是可以实现持久保存在内存中的,而无需每次请求都重新加载。 unsigned char nApplyCount; zend_bool bApplyProtection; } HashTable;
typedef struct bucket { ulong h; //数组索引 uint nKeyLength; //字符串索引的长度 void *pData; //实际数据的存储地址 void *pDataPtr; //引入的数据存储地址 struct bucket *pListNext; struct bucket *pListLast; struct bucket *pNext; //双向链表的下一个元素的地址 struct bucket *pLast;//双向链表的下一个元素地址 char arKey[1]; /* Must be last element */ } Bucket;
以上が低いメモリ使用率と弱い型の PHP 配列の例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。