Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:1903 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 76748 invoked from network); 22 May 2003 18:18:35 -0000 Received: from unknown (HELO carmine.bestweb.net) (209.94.102.73) by pb1.pair.com with SMTP; 22 May 2003 18:18:35 -0000 Received: from [192.168.1.102] (ip216-179-71-153.cust.bestweb.net [216.179.71.153]) by carmine.bestweb.net (Postfix) with ESMTP id 00DA522F28; Thu, 22 May 2003 13:18:30 -0500 (EST) To: internals@lists.php.net Cc: andi@zend.com, Zeev Suraski Content-Type: multipart/mixed; boundary="=-h3snVdyaz7AmGAoQQHYy" Organization: Message-ID: <1053622345.28527.44.camel@hasele> Mime-Version: 1.0 X-Mailer: Ximian Evolution 1.2.4 Date: 22 May 2003 12:52:25 -0400 Subject: HANDLE_NUMERIC() From: sterling@bumblebury.com (Sterling Hughes) --=-h3snVdyaz7AmGAoQQHYy Content-Type: text/plain Content-Transfer-Encoding: 7bit Hi, I've attached a small patch which removes HANDLE_NUMERIC() from zend_hash.c, and moves it instead to the necessary places in zend_execute.c, in the form of a zend_is_numeric_key() function defined in zend_operators.c Anyhow, I'm getting a really nice performance increase. Although it depends on the usage, it certainly makes pretty much everything zippier (and dare I say sexier. :) -Sterling -- "First they ignore you, then they laugh at you, then they fight you, then you win." - Gandhi --=-h3snVdyaz7AmGAoQQHYy Content-Disposition: attachment; filename=handle_numeric.diff Content-Type: text/x-patch; name=handle_numeric.diff; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Index: zend_execute.c =================================================================== RCS file: /repository/ZendEngine2/zend_execute.c,v retrieving revision 1.463 diff -u -r1.463 zend_execute.c --- zend_execute.c 21 May 2003 21:59:39 -0000 1.463 +++ zend_execute.c 22 May 2003 18:15:44 -0000 @@ -727,6 +727,7 @@ zval **retval; char *offset_key; int offset_key_length; + long index; switch (dim->type) { case IS_NULL: @@ -734,9 +735,13 @@ offset_key_length = 0; goto fetch_string_dim; case IS_STRING: + if (zend_is_numeric_key(dim, &index)) { + goto fetch_int_dim; + } + offset_key = dim->value.str.val; offset_key_length = dim->value.str.len; - + fetch_string_dim: if (zend_hash_find(ht, offset_key, offset_key_length+1, (void **) &retval) == FAILURE) { switch (type) { @@ -762,33 +767,31 @@ case IS_DOUBLE: case IS_RESOURCE: case IS_BOOL: - case IS_LONG: { - long index; + case IS_LONG: + if (dim->type == IS_DOUBLE) { + index = (long)dim->value.dval; + } else { + index = dim->value.lval; + } +fetch_int_dim: + if (zend_hash_index_find(ht, index, (void **) &retval) == FAILURE) { + switch (type) { + case BP_VAR_R: + zend_error(E_NOTICE,"Undefined offset: %d", index); + /* break missing intentionally */ + case BP_VAR_IS: + retval = &EG(uninitialized_zval_ptr); + break; + case BP_VAR_RW: + zend_error(E_NOTICE,"Undefined offset: %d", index); + /* break missing intentionally */ + case BP_VAR_W: { + zval *new_zval = &EG(uninitialized_zval); - if (dim->type == IS_DOUBLE) { - index = (long)dim->value.dval; - } else { - index = dim->value.lval; - } - if (zend_hash_index_find(ht, index, (void **) &retval) == FAILURE) { - switch (type) { - case BP_VAR_R: - zend_error(E_NOTICE,"Undefined offset: %d", index); - /* break missing intentionally */ - case BP_VAR_IS: - retval = &EG(uninitialized_zval_ptr); - break; - case BP_VAR_RW: - zend_error(E_NOTICE,"Undefined offset: %d", index); - /* break missing intentionally */ - case BP_VAR_W: { - zval *new_zval = &EG(uninitialized_zval); - - new_zval->refcount++; - zend_hash_index_update(ht, index, &new_zval, sizeof(zval *), (void **) &retval); - } - break; + new_zval->refcount++; + zend_hash_index_update(ht, index, &new_zval, sizeof(zval *), (void **) &retval); } + break; } } break; @@ -3286,9 +3289,16 @@ case IS_BOOL: zend_hash_index_update(array_ptr->value.ht, offset->value.lval, &expr_ptr, sizeof(zval *), NULL); break; - case IS_STRING: - zend_hash_update(array_ptr->value.ht, offset->value.str.val, offset->value.str.len+1, &expr_ptr, sizeof(zval *), NULL); + case IS_STRING: { + long idx; + + if (zend_is_numeric_key(offset, &idx)) { + zend_hash_index_update(array_ptr->value.ht, idx, &expr_ptr, sizeof(zval *), NULL); + } else { + zend_hash_update(array_ptr->value.ht, offset->value.str.val, offset->value.str.len+1, &expr_ptr, sizeof(zval *), NULL); + } break; + } case IS_NULL: zend_hash_update(array_ptr->value.ht, "", sizeof(""), &expr_ptr, sizeof(zval *), NULL); break; @@ -3508,6 +3518,7 @@ { zval **container = get_obj_zval_ptr_ptr(&EX(opline)->op1, EX(Ts), BP_VAR_R TSRMLS_CC); zval *offset = get_zval_ptr(&EX(opline)->op2, EX(Ts), &EG(free_op2), BP_VAR_R); + long index; if (container) { HashTable *ht; @@ -3526,20 +3537,20 @@ case IS_RESOURCE: case IS_BOOL: case IS_LONG: - { - long index; - - if (offset->type == IS_DOUBLE) { - index = (long) offset->value.lval; - } else { - index = offset->value.lval; - } + if (offset->type == IS_DOUBLE) { + index = (long) offset->value.lval; + } else { + index = offset->value.lval; + } + zend_hash_index_del(ht, index); + break; + case IS_STRING: + if (zend_is_numeric_key(offset, &index)) { zend_hash_index_del(ht, index); - break; + } else { + zend_hash_del(ht, offset->value.str.val, offset->value.str.len+1); } - case IS_STRING: - zend_hash_del(ht, offset->value.str.val, offset->value.str.len+1); break; case IS_NULL: zend_hash_del(ht, "", sizeof("")); @@ -3730,6 +3741,7 @@ zval *offset = get_zval_ptr(&EX(opline)->op2, EX(Ts), &EG(free_op2), BP_VAR_R); zval **value = NULL; int result = 0; + long index; if (container) { if ((*container)->type == IS_ARRAY) { @@ -3743,21 +3755,21 @@ case IS_RESOURCE: case IS_BOOL: case IS_LONG: - { - long index; - - if (offset->type == IS_DOUBLE) { - index = (long) offset->value.lval; - } else { - index = offset->value.lval; - } + if (offset->type == IS_DOUBLE) { + index = (long) offset->value.lval; + } else { + index = offset->value.lval; + } + if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) { + isset = 1; + } + break; + case IS_STRING: + if (zend_is_numeric_key(offset, &index)) { if (zend_hash_index_find(ht, index, (void **) &value) == SUCCESS) { isset = 1; } - break; - } - case IS_STRING: - if (zend_hash_find(ht, offset->value.str.val, offset->value.str.len+1, (void **) &value) == SUCCESS) { + } else if (zend_hash_find(ht, offset->value.str.val, offset->value.str.len+1, (void **) &value) == SUCCESS) { isset = 1; } break; Index: zend_hash.c =================================================================== RCS file: /repository/ZendEngine2/zend_hash.c,v retrieving revision 1.99 diff -u -r1.99 zend_hash.c --- zend_hash.c 6 Feb 2003 00:14:49 -0000 1.99 +++ zend_hash.c 22 May 2003 18:15:46 -0000 @@ -21,32 +21,6 @@ #include "zend.h" -#define HANDLE_NUMERIC(key, length, func) { \ - register char *tmp=key; \ - \ - if ((*tmp>='0' && *tmp<='9')) do { /* possibly a numeric index */ \ - char *end=tmp+length-1; \ - ulong idx; \ - \ - if (*tmp++=='0' && length>2) { /* don't accept numbers with leading zeros */ \ - break; \ - } \ - while (tmp='0' && *tmp<='9')) { \ - break; \ - } \ - tmp++; \ - } \ - if (tmp==end && *tmp=='\0') { /* a numeric index */ \ - idx = strtol(key, NULL, 10); \ - if (idx!=LONG_MAX) { \ - return func; \ - } \ - } \ - } while (0); \ -} - - #define CONNECT_TO_BUCKET_DLLIST(element, list_head) \ (element)->pNext = (list_head); \ (element)->pLast = NULL; \ @@ -224,8 +198,6 @@ return FAILURE; } - HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_update_or_next_insert(ht, idx, pData, nDataSize, pDest, flag)); - h = zend_inline_hash_func(arKey, nKeyLength); nIndex = h & ht->nTableMask; @@ -474,7 +446,6 @@ IS_CONSISTENT(ht); if (flag == HASH_DEL_KEY) { - HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_del_key_or_index(ht, arKey, nKeyLength, idx, HASH_DEL_INDEX)); h = zend_inline_hash_func(arKey, nKeyLength); } nIndex = h & ht->nTableMask; @@ -866,8 +837,6 @@ IS_CONSISTENT(ht); - HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_find(ht, idx, pData)); - h = zend_inline_hash_func(arKey, nKeyLength); nIndex = h & ht->nTableMask; @@ -920,8 +889,6 @@ IS_CONSISTENT(ht); - HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_exists(ht, idx)); - h = zend_inline_hash_func(arKey, nKeyLength); nIndex = h & ht->nTableMask; @@ -948,8 +915,6 @@ } IS_CONSISTENT(ht); - - HANDLE_NUMERIC(arKey, nKeyLength, zend_hash_index_exists(ht, idx)); nIndex = h & ht->nTableMask; Index: zend_operators.c =================================================================== RCS file: /repository/ZendEngine2/zend_operators.c,v retrieving revision 1.152 diff -u -r1.152 zend_operators.c --- zend_operators.c 21 May 2003 22:36:09 -0000 1.152 +++ zend_operators.c 22 May 2003 18:15:49 -0000 @@ -33,6 +33,41 @@ #include "ext/bcmath/number.h" #endif +ZEND_API zend_bool zend_is_numeric_key(zval *zvalue, long *val) +{ + char *tmp; + long length; + + tmp = zvalue->value.str.val; + length = zvalue->value.str.len; + + if ((*tmp>='0' && *tmp<='9')) { /* possibly a numeric index */ + char *end=tmp+length; + ulong idx; + + if (*tmp++=='0' && length>2) { /* don't accept numbers with leading zeros */ + return 0; + } + + while (tmp='0' && *tmp<='9')) { + break; + } + tmp++; + } + + if (tmp==end && *tmp=='\0') { /* a numeric index */ + idx = strtol(zvalue->value.str.val, NULL, 10); + if (idx!=LONG_MAX) { + *val = idx; + return 1; + } + } + } + + return 0; +} + ZEND_API int zend_atoi(const char *str, int str_len) { int retval; Index: zend_operators.h =================================================================== RCS file: /repository/ZendEngine2/zend_operators.h,v retrieving revision 1.76 diff -u -r1.76 zend_operators.h --- zend_operators.h 21 May 2003 22:36:09 -0000 1.76 +++ zend_operators.h 22 May 2003 18:15:50 -0000 @@ -60,6 +60,7 @@ ZEND_API int is_smaller_or_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC); ZEND_API zend_bool instanceof_function(zend_class_entry *instance_ce, zend_class_entry *ce TSRMLS_DC); +ZEND_API zend_bool zend_is_numeric_key(zval *, long *); static inline zend_bool is_numeric_string(char *str, int length, long *lval, double *dval, zend_bool allow_errors) { --=-h3snVdyaz7AmGAoQQHYy--