From: Sascha Schumann Date: Sun, 21 Apr 2002 01:17:49 +0000 (+0000) Subject: simplify and improve speed of smart_str_print_long. X-Git-Tag: php-4.3.0dev-ZendEngine2-Preview1~530 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d30fc27e5afeda9a548150adb46a557dd554ceca;p=php simplify and improve speed of smart_str_print_long. also add a variant for unsigned numbers. --- diff --git a/ext/standard/php_smart_str.h b/ext/standard/php_smart_str.h index bf9e3a63ad..c0c2e770bb 100644 --- a/ext/standard/php_smart_str.h +++ b/ext/standard/php_smart_str.h @@ -47,6 +47,7 @@ #define smart_str_appendl(dest, src, len) smart_str_appendl_ex(dest, src, len, 0) #define smart_str_append(dest, src) smart_str_append_ex(dest, src, 0) #define smart_str_append_long(dest, val) smart_str_append_long_ex(dest, val, 0) +#define smart_str_append_unsigned(dest, val) smart_str_append_unsigned_ex(dest, val, 0) static inline void smart_str_appendc_ex(smart_str *dest, char c, int what) { @@ -76,47 +77,50 @@ static inline void smart_str_appendl_ex(smart_str *dest, const char *src, size_t dest->len = newlen; } -static inline char *smart_str_print_long(char *buf, long num) +/* buf points to the END of the buffer */ +static inline char *smart_str_print_unsigned(char *buf, unsigned long num) { - char *p = buf, *end; - int n; - long tmp; - - if (num < 0) { - num = -num; - *p++ = '-'; - } - - /* many numbers are < 10 */ - if (num < 10) { - *p++ = num + '0'; - return p; - } - - n = 1; - tmp = num; - - /* calculate the number of digits we need */ - do { - tmp /= 10; - n++; - } while (tmp >= 10); - - end = p += n; + char *p = buf; + *p = '\0'; do { *--p = (num % 10) + '0'; num /= 10; - } while (--n > 0); + } while (num > 0); + + return p; +} - return end; +/* buf points to the END of the buffer */ +static inline char *smart_str_print_long(char *buf, long num) +{ + char *p; + + if (num < 0) { + /* this might cause problems when dealing with LONG_MIN + and machines which don't support long long. Works + flawlessly on 32bit x86 */ + p = smart_str_print_unsigned(buf, -num); + *--p = '-'; + } else { + p = smart_str_print_unsigned(buf, num); + } + + return p; } static inline void smart_str_append_long_ex(smart_str *dest, long num, int type) { char buf[32]; - char *p = smart_str_print_long(buf, num); - smart_str_appendl_ex(dest, buf, p - buf, type); + char *p = smart_str_print_long(buf + sizeof(buf) - 1, num); + smart_str_appendl_ex(dest, p, (buf + sizeof(buf) - 1) - p, type); +} + +static inline void smart_str_append_unsigned_ex(smart_str *dest, long num, int type) +{ + char buf[32]; + char *p = smart_str_print_unsigned(buf + sizeof(buf) - 1, num); + smart_str_appendl_ex(dest, p, (buf + sizeof(buf) - 1) - p, type); } static inline void smart_str_append_ex(smart_str *dest, smart_str *src, int what) diff --git a/ext/standard/var.c b/ext/standard/var.c index 82dc118167..4b8e661aae 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -379,11 +379,13 @@ static inline int php_add_var_hash(HashTable *var_hash, zval *var, void *var_old { ulong var_no; char id[32], *p; + register int len; - p = smart_str_print_long(id, (long) var); - *p = '\0'; - - if (var_old && zend_hash_find(var_hash, id, p - id, var_old) == SUCCESS) { + /* relies on "(long)" being a perfect hash function for data pointers */ + p = smart_str_print_long(id + sizeof(id) - 1, (long) var); + len = id + sizeof(id) - 1 - p; + + if (var_old && zend_hash_find(var_hash, p, len, var_old) == SUCCESS) { if (!var->is_ref) { /* we still need to bump up the counter, since non-refs will be counted separately by unserializer */ @@ -395,7 +397,7 @@ static inline int php_add_var_hash(HashTable *var_hash, zval *var, void *var_old /* +1 because otherwise hash will think we are trying to store NULL pointer */ var_no = zend_hash_num_elements(var_hash) + 1; - zend_hash_add(var_hash, id, p - id, &var_no, sizeof(var_no), NULL); + zend_hash_add(var_hash, p, len, &var_no, sizeof(var_no), NULL); return SUCCESS; }