为什么用C/C++写PHP
两个字概括,性能。
在PHP里面,所有变量都是弱类型的,这样的话,PHP上手很快,很适合初学者。
有利即有弊,以下测试证明了这点。
运行以下代码,输出结果为 54.373bytes
<?php
$start = memory_get_usage();
$a = array_fill(0, 1000, 1);
$end = memory_get_usage();
echo ($end - $start)/1000 .'kbytes' . '<br>';
这表明1000个数组变量,平均每个变量损失的内存为54byte.
但是,我们知道,我们定于的都是简单的整型变量,C语言中,只需要 4byte.
关于memory_get_usage用法,点击这里. php:memory_get_usage
为什么会这样
typedef struct _zval_struct zval;
struct _zval_struct {
/* Variable information */
zvalue_value value; /* value */
zend_uint refcount__gc;
zend_uchar type; /* active type */
zend_uchar is_ref__gc;
};
typedef union _zvalue_value {
long lval; /* long value */
double dval; /* double value */
struct {
char *val;
int len;
} str;
HashTable *ht; /* hash table value */
zend_object_value obj;
} zvalue_value;
一个变量,在PHP内核里面以 zval 结构体形式存在.对于一个 zval结构,最小需要14个字节。
同时,每一个数组变量存储在HashTable中的Bucket中,结构如下
typedef struct _hashtable {
uint nTableSize;//4
uint nTableMask;//4
uint nNumOfElements;//4
ulong nNextFreeElement;//4
Bucket *pInternalPointer; /* 4*/
Bucket *pListHead;//4
Bucket *pListTail;//4
Bucket **arBuckets;//4
dtor_func_t pDestructor;//4
zend_bool persistent;//1
unsigned char nApplyCount;//1
zend_bool bApplyProtection;//1
#if ZEND_DEBUG
int inconsistent;//4
#endif
} HashTable;
typedef struct bucket {
ulong h; /* Used for numeric indexing 4字节 */
uint nKeyLength; /* The length of the key (for string keys) 4字节 */
void *pData; /* 4字节*/
void *pDataPtr; /* 4字节*/
struct bucket *pListNext; /* PHP arrays are ordered. This gives the next element in that order4字节*/
struct bucket *pListLast; /* and this gives the previous element 4字节 */
struct bucket *pNext; /* The next element in this (doubly) linked list 4字节*/
struct bucket *pLast; /* The previous element in this (doubly) linked list 4字节*/
char arKey[1]; /* Must be last element 1字节*/
} Bucket
不用关心HashTable所占的内存,因为每个数组,只创建一个。这里的HashTable使用的是开链法解决冲突。
bucket为每个元素的载体,占内存为33个字节,但是最后一个元素为char arKey[1],所有后面还可能有其它的数据。
对于整数类型的Key,这里就是一个字节,但是对于字符串类型的Key,就是就是整个Key的长度了。然后考虑到内存对齐,这里至少占用 36个字节。
因此,一个数组元素,占的内存最少为 36+14 = 52字节;
总结
从上面的分析中,可以看出,PHP内存利用率,相对于C,为 10%
这也就是为什么需要写PHP扩展的原因,当应用出现内存严重不足的情况下,可以考虑使用PHP扩展,重写内存占用最高的地方。