php7 变量,PHP7变量结构分析
PHP7相對(duì)于PHP5提升了將近一倍的性能,下面我將針對(duì)PHP7與PHP5的變量結(jié)構(gòu)實(shí)現(xiàn)進(jìn)行對(duì)比,分析為什么PHP7性能提升。當(dāng)然變量結(jié)構(gòu)修改只是PHP7性能提升中的一部分原因,還有很多原因比如HashTable結(jié)構(gòu)變更、減少內(nèi)存分配次數(shù)、多使用棧內(nèi)存等等,本文只對(duì)變量結(jié)構(gòu)進(jìn)行分析。
本文源碼基于PHP7.2.3以及PHP5.6.34
PHP作為弱類型語言,所有變量都是zval結(jié)構(gòu)體來保存,PHP7與PHP5的zval結(jié)構(gòu)也不相同,下面將分析兩者zval結(jié)構(gòu)的不同之處。
PHP5
PHP5的zval定義于Zend\zend.h
typedef struct _zval_struct zval; //此段代碼在Zend\zend_types.h中
...
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;
zend_ast *ast;
} zvalue_value;
struct _zval_struct {
/* Variable information */
zvalue_value value; /* value */
zend_uint refcount__gc;
zend_uchar type; /* active type */
zend_uchar is_ref__gc;
};
可以看到zval結(jié)構(gòu)體有四個(gè)成員:
zvalue_value:共用體,儲(chǔ)存變量的值
refcount__gc:引用計(jì)數(shù),用于垃圾回收,默認(rèn)值1
type:變量的具體類型
is_ref__gc:是否引用,用于垃圾回收,默認(rèn)值0
zvalue_value共用體用來儲(chǔ)存變量的值:
long lval成員用于儲(chǔ)存整型與布爾型。
double dval成員用于儲(chǔ)存 浮點(diǎn)型。
結(jié)構(gòu)體str用于存儲(chǔ)字符串,之所以使用結(jié)構(gòu)體是用來儲(chǔ)存字符串的長度,實(shí)時(shí)獲取字符串的長度的時(shí)間復(fù)雜度是O(n),在PHP中字符串的操作非常頻繁,這樣能節(jié)省大量的時(shí)間。
HashTable *ht用來存儲(chǔ)數(shù)組,PHP中的數(shù)組非常強(qiáng)大,這一切都基于哈希表結(jié)構(gòu)。
zend_object_value obj用來存儲(chǔ)對(duì)象。在面向?qū)ο缶幊讨?#xff0c;這也是非常重要的一部分。
zend_ast *ast zend抽象語法樹,zend內(nèi)核使用。
zval結(jié)構(gòu)體中的type成員有以下幾種類型(代碼位于Zend\zend.h):
/* data types */
/* All data types <= IS_BOOL have their constructor/destructors skipped */
#define IS_NULL 0 #define IS_LONG 1 #define IS_DOUBLE 2 #define IS_BOOL 3 #define IS_ARRAY 4 #define IS_OBJECT 5 #define IS_STRING 6 #define IS_RESOURCE 7 #define IS_CONSTANT 8 #define IS_CONSTANT_AST 9 #define IS_CALLABLE 10
PHP7
PHP7的zval定義于Zend\zend_types.h
typedef struct _zval_struct zval;
...
typedef union _zend_value {
zend_long lval;/* long value */
double dval;/* double value */
zend_refcounted *counted;
zend_string *str;
zend_array *arr;
zend_object *obj;
zend_resource *res;
zend_reference *ref;
zend_ast_ref *ast;
zval *zv;
void *ptr;
zend_class_entry *ce;
zend_function *func;
struct {
uint32_t w1;
uint32_t w2;
} ww;
} zend_value;
struct _zval_struct {
zend_value value;/* value */
union {
struct {
ZEND_ENDIAN_LOHI_4(
zend_uchar type,/* active type */
zend_uchar type_flags,
zend_uchar const_flags,
zend_uchar reserved) /* call info for EX(This) */
} v;
uint32_t type_info;
} u1;
union {
uint32_t next; /* hash collision chain */
uint32_t cache_slot; /* literal cache slot */
uint32_t lineno; /* line number (for ast nodes) */
uint32_t num_args; /* arguments number for EX(This) */
uint32_t fe_pos; /* foreach position */
uint32_t fe_iter_idx; /* foreach iterator index */
uint32_t access_flags; /* class constant access flags */
uint32_t property_guard; /* single property guard */
uint32_t extra; /* not further specified */
} u2;
};
可以看到PHP7的代碼相對(duì)PHP5的代碼更加符合規(guī)范,所以更便于理解。
在_zval_struct結(jié)構(gòu)體中:
zend_value共用體用于儲(chǔ)存變量的值
u1共用體,用于存儲(chǔ)變量的類型,以及一些輔助值
u2共用體,輔助值,由于內(nèi)存對(duì)齊,_zval_struct結(jié)構(gòu)體總共16字節(jié)大小,zend_value為8字節(jié),u1為4字節(jié),剩下的4字節(jié)防止浪費(fèi),用來作為輔助值,具體輔助用來干嘛代碼的注釋已經(jīng)說明了。
u2共用體的輔助值成員一直在增加,我記得當(dāng)時(shí)PHP7剛發(fā)布的時(shí)候才4個(gè)輔助值,現(xiàn)在已經(jīng)9個(gè)了。
zend_value共用體就不用解釋了,相比PHP5,PHP7的代碼結(jié)構(gòu)更加清晰、規(guī)范,一眼就能看出共用體的成員都用來儲(chǔ)存什么類型的數(shù)據(jù),我們可以發(fā)現(xiàn)PHP7 zend_value共用體大部分?jǐn)?shù)據(jù)都是存儲(chǔ)的指針,由于指針占的內(nèi)存小,所以PHP7的zend_value占的內(nèi)存比PHP5的zend_value要小。
對(duì)比
我們可以看到雖然PHP7的變量結(jié)構(gòu)看起來更復(fù)雜,但是由于使用共用體,所以其實(shí)內(nèi)存占用并不多,PHP5中的zval占用24個(gè)字節(jié),PHP7中的zval占用16個(gè)字節(jié)。內(nèi)存占用減少了1/3,而且PHP中的代碼邏輯都是基于變量來實(shí)現(xiàn)的,所以對(duì)性能的影響非常大。可以看到PHP7中的代碼規(guī)范比PHP5好了很多,并且PHP7的變量結(jié)構(gòu)中輔助值的使用充分利用了內(nèi)存,同時(shí)提高了性能。
結(jié)語
PHP7主要是優(yōu)化性能,其實(shí)這個(gè)和互聯(lián)網(wǎng)的發(fā)展也有關(guān)系。在之前,訪問量和性能并不是最主要的,PHP憑借敏捷開發(fā)能在編程語言中占據(jù)一席之地。然而隨著互聯(lián)網(wǎng)的發(fā)展,網(wǎng)民數(shù)量的增多,以及各種編程語言的出現(xiàn),大多數(shù)大型網(wǎng)站追求的是高并發(fā)以及訪問速度,這個(gè)時(shí)候PHP的劣勢(shì)就展示出來了。當(dāng)然可以感受到PHP社區(qū)對(duì)這門語言的熱情,包括PHP7的性能提升,swoole擴(kuò)展的流行,以及正在開發(fā)中的PHP JIT版本,相信PHP會(huì)發(fā)展的越來越好。
總結(jié)
以上是生活随笔為你收集整理的php7 变量,PHP7变量结构分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php设置路径别名,react设置文件路
- 下一篇: manifest php,Laravel