summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2015-01-14 15:04:04 +0300
committerDmitry Stogov <dmitry@zend.com>2015-01-14 15:04:04 +0300
commit588e803e8522434d769315fecf309ad12c9bfd69 (patch)
tree0c3da8d1ab9974f263626231add4019f0804b01c
parentd5b5ad72b633b24d8f669d43f8e1c6a78de79b12 (diff)
downloadphp-git-588e803e8522434d769315fecf309ad12c9bfd69.tar.gz
Ipmrove strtr() by maintaining a set of characters that may start a matched pattern and avoid zend_hash_find() calls for other paterns.
-rw-r--r--ext/standard/string.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/ext/standard/string.c b/ext/standard/string.c
index 0566542234..bd27e064c8 100644
--- a/ext/standard/string.c
+++ b/ext/standard/string.c
@@ -2903,10 +2903,12 @@ static void php_strtr_array(zval *return_value, char *str, size_t slen, HashTabl
zval *entry, tmp, dummy;
char *key;
smart_str result = {0};
+ zend_ulong bitset[256/sizeof(zend_ulong)];
/* we will collect all possible key lengths */
ZVAL_NULL(&dummy);
zend_hash_init(&num_hash, 8, NULL, NULL, 0);
+ memset(bitset, 0, sizeof(bitset));
/* check if original array has numeric keys */
ZEND_HASH_FOREACH_KEY(pats, num_key, str_key) {
@@ -2928,6 +2930,7 @@ static void php_strtr_array(zval *return_value, char *str, size_t slen, HashTabl
}
/* remember possible key length */
zend_hash_index_add(&num_hash, len, &dummy);
+ bitset[((unsigned char)str_key->val[0]) / sizeof(zend_ulong)] |= Z_UL(1) << (((unsigned char)str_key->val[0]) % sizeof(zend_ulong));
}
} ZEND_HASH_FOREACH_END();
@@ -2953,6 +2956,7 @@ static void php_strtr_array(zval *return_value, char *str, size_t slen, HashTabl
}
/* remember possible key length */
zend_hash_index_add(&num_hash, len, &dummy);
+ bitset[((unsigned char)str_key->val[0]) / sizeof(zend_ulong)] |= Z_UL(1) << (((unsigned char)str_key->val[0]) % sizeof(zend_ulong));
} else {
len = str_key->len;
if (UNEXPECTED(len > slen)) {
@@ -2989,6 +2993,7 @@ static void php_strtr_array(zval *return_value, char *str, size_t slen, HashTabl
key = str + pos;
ZEND_HASH_FOREACH_NUM_KEY(&num_hash, len) {
if (len > slen - pos) continue;
+ if ((bitset[((unsigned char)key[0]) / sizeof(zend_ulong)] & Z_UL(1) << (((unsigned char)key[0]) % sizeof(zend_ulong))) == 0) continue;
entry = zend_hash_str_find(pats, key, len);
if (entry != NULL) {
zend_string *str = zval_get_string(entry);
@@ -3014,6 +3019,7 @@ static void php_strtr_array(zval *return_value, char *str, size_t slen, HashTabl
found = 0;
key = str + pos;
for (len = maxlen; len >= minlen; len--) {
+ if ((bitset[((unsigned char)key[0]) / sizeof(zend_ulong)] & Z_UL(1) << (((unsigned char)key[0]) % sizeof(zend_ulong))) == 0) continue;
entry = zend_hash_str_find(pats, key, len);
if (entry != NULL) {
zend_string *str = zval_get_string(entry);