php7 变量,PHP7变量结构分析
PHP7相對于PHP5提升了將近一倍的性能,下面我將針對PHP7與PHP5的變量結構實現進行對比,分析為什么PHP7性能提升。當然變量結構修改只是PHP7性能提升中的一部分原因,還有很多原因比如HashTable結構變更、減少內存分配次數、多使用棧內存等等,本文只對變量結構進行分析。
本文源碼基于PHP7.2.3以及PHP5.6.34
PHP作為弱類型語言,所有變量都是zval結構體來保存,PHP7與PHP5的zval結構也不相同,下面將分析兩者zval結構的不同之處。
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結構體有四個成員:
zvalue_value:共用體,儲存變量的值
refcount__gc:引用計數,用于垃圾回收,默認值1
type:變量的具體類型
is_ref__gc:是否引用,用于垃圾回收,默認值0
zvalue_value共用體用來儲存變量的值:
long lval成員用于儲存整型與布爾型。
double dval成員用于儲存 浮點型。
結構體str用于存儲字符串,之所以使用結構體是用來儲存字符串的長度,實時獲取字符串的長度的時間復雜度是O(n),在PHP中字符串的操作非常頻繁,這樣能節省大量的時間。
HashTable *ht用來存儲數組,PHP中的數組非常強大,這一切都基于哈希表結構。
zend_object_value obj用來存儲對象。在面向對象編程中,這也是非常重要的一部分。
zend_ast *ast zend抽象語法樹,zend內核使用。
zval結構體中的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的代碼相對PHP5的代碼更加符合規范,所以更便于理解。
在_zval_struct結構體中:
zend_value共用體用于儲存變量的值
u1共用體,用于存儲變量的類型,以及一些輔助值
u2共用體,輔助值,由于內存對齊,_zval_struct結構體總共16字節大小,zend_value為8字節,u1為4字節,剩下的4字節防止浪費,用來作為輔助值,具體輔助用來干嘛代碼的注釋已經說明了。
u2共用體的輔助值成員一直在增加,我記得當時PHP7剛發布的時候才4個輔助值,現在已經9個了。
zend_value共用體就不用解釋了,相比PHP5,PHP7的代碼結構更加清晰、規范,一眼就能看出共用體的成員都用來儲存什么類型的數據,我們可以發現PHP7 zend_value共用體大部分數據都是存儲的指針,由于指針占的內存小,所以PHP7的zend_value占的內存比PHP5的zend_value要小。
對比
我們可以看到雖然PHP7的變量結構看起來更復雜,但是由于使用共用體,所以其實內存占用并不多,PHP5中的zval占用24個字節,PHP7中的zval占用16個字節。內存占用減少了1/3,而且PHP中的代碼邏輯都是基于變量來實現的,所以對性能的影響非常大。可以看到PHP7中的代碼規范比PHP5好了很多,并且PHP7的變量結構中輔助值的使用充分利用了內存,同時提高了性能。
結語
PHP7主要是優化性能,其實這個和互聯網的發展也有關系。在之前,訪問量和性能并不是最主要的,PHP憑借敏捷開發能在編程語言中占據一席之地。然而隨著互聯網的發展,網民數量的增多,以及各種編程語言的出現,大多數大型網站追求的是高并發以及訪問速度,這個時候PHP的劣勢就展示出來了。當然可以感受到PHP社區對這門語言的熱情,包括PHP7的性能提升,swoole擴展的流行,以及正在開發中的PHP JIT版本,相信PHP會發展的越來越好。
總結
以上是生活随笔為你收集整理的php7 变量,PHP7变量结构分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php设置路径别名,react设置文件路
- 下一篇: manifest php,Laravel