com php-src: Optimized range: ext/standard/array.c
| From: | Xinchen Hui | Date: | Tue, 20 Jan 2015 14:02:11 +0000 |
| Subject: | com php-src: Optimized range: ext/standard/array.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-84201@lists.php.net to get a copy of this message | ||
Commit: afa666f65001ec114ee03d31d1a426491da71001
Author: Xinchen Hui <laruence@php.net> Tue, 20 Jan 2015 21:50:31 +0800
Parents: 8fb29d3f630842b3fe2ac2b3c030d71007db5c48
Branches: master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=afa666f65001ec114ee03d31d1a426491da71001
Log:
Optimized range
Changed paths:
M ext/standard/array.c
Diff:
diff --git a/ext/standard/array.c b/ext/standard/array.c
index 617392b..5840285 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -1663,15 +1663,12 @@ PHP_FUNCTION(array_fill_keys)
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(keys), entry) {
ZVAL_DEREF(entry);
+ Z_TRY_ADDREF_P(val);
if (Z_TYPE_P(entry) == IS_LONG) {
- Z_TRY_ADDREF_P(val);
zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_P(entry), val);
} else {
zend_string *key = zval_get_string(entry);
-
- Z_TRY_ADDREF_P(val);
zend_symtable_update(Z_ARRVAL_P(return_value), key, val);
-
zend_string_release(key);
}
} ZEND_HASH_FOREACH_END();
@@ -1705,9 +1702,6 @@ PHP_FUNCTION(range)
}
}
- /* Initialize the return_value as an array. */
- array_init(return_value);
-
/* If the range is given as strings, generate an array of characters. */
if (Z_TYPE_P(zlow) == IS_STRING && Z_TYPE_P(zhigh) == IS_STRING &&
Z_STRLEN_P(zlow) >= 1 && Z_STRLEN_P(zhigh) >= 1) {
int type1, type2;
@@ -1731,34 +1725,44 @@ PHP_FUNCTION(range)
err = 1;
goto err;
}
- for (; low >= high; low -= (unsigned int)lstep) {
- if (CG(one_char_string)[low]) {
- ZVAL_INTERNED_STR(&tmp, CG(one_char_string)[low]);
- } else {
- ZVAL_STRINGL(&tmp, (char*)&low, 1);
- }
- zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
- if (((signed int)low - lstep) < 0) {
- break;
+ /* Initialize the return_value as an array. */
+ array_init_size(return_value, ((low - high) / lstep) + 1);
+ zend_hash_real_init(Z_ARRVAL_P(return_value), 1);
+ ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) {
+ for (; low >= high; low -= (unsigned int)lstep) {
+ if (CG(one_char_string)[low]) {
+ ZVAL_INTERNED_STR(&tmp, CG(one_char_string)[low]);
+ } else {
+ ZVAL_STRINGL(&tmp, (char*)&low, 1);
+ }
+ ZEND_HASH_FILL_ADD(&tmp);
+ if (((signed int)low - lstep) < 0) {
+ break;
+ }
}
- }
+ } ZEND_HASH_FILL_END();
} else if (high > low) { /* Positive Steps */
if (lstep <= 0) {
err = 1;
goto err;
}
- for (; low <= high; low += (unsigned int)lstep) {
- if (CG(one_char_string)[low]) {
- ZVAL_INTERNED_STR(&tmp, CG(one_char_string)[low]);
- } else {
- ZVAL_STRINGL(&tmp, (char*)&low, 1);
- }
- zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
- if (((signed int)low + lstep) > 255) {
- break;
+ array_init_size(return_value, ((high - low) / lstep) + 1);
+ zend_hash_real_init(Z_ARRVAL_P(return_value), 1);
+ ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) {
+ for (; low <= high; low += (unsigned int)lstep) {
+ if (CG(one_char_string)[low]) {
+ ZVAL_INTERNED_STR(&tmp, CG(one_char_string)[low]);
+ } else {
+ ZVAL_STRINGL(&tmp, (char*)&low, 1);
+ }
+ ZEND_HASH_FILL_ADD(&tmp);
+ if (((signed int)low + lstep) > 255) {
+ break;
+ }
}
- }
+ } ZEND_HASH_FILL_END();
} else {
+ array_init(return_value);
if (CG(one_char_string)[low]) {
ZVAL_INTERNED_STR(&tmp, CG(one_char_string)[low]);
} else {
@@ -1766,7 +1770,6 @@ PHP_FUNCTION(range)
}
zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
}
-
} else if (Z_TYPE_P(zlow) == IS_DOUBLE || Z_TYPE_P(zhigh) == IS_DOUBLE || is_step_double) {
double low, high, value;
zend_long i;
@@ -1782,21 +1785,30 @@ double_str:
goto err;
}
+ array_init_size(return_value, ((low - high) / step) + 1);
+ zend_hash_real_init(Z_ARRVAL_P(return_value), 1);
+ ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) {
for (value = low; value >= (high - DOUBLE_DRIFT_FIX); value = low - (++i * step)) {
Z_DVAL(tmp) = value;
- zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
+ ZEND_HASH_FILL_ADD(&tmp);
}
+ } ZEND_HASH_FILL_END();
} else if (high > low) { /* Positive steps */
if (high - low < step || step <= 0) {
err = 1;
goto err;
}
- for (value = low; value <= (high + DOUBLE_DRIFT_FIX); value = low + (++i * step)) {
- Z_DVAL(tmp) = value;
- zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
- }
+ array_init_size(return_value, ((high - low) / step) + 1);
+ zend_hash_real_init(Z_ARRVAL_P(return_value), 1);
+ ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) {
+ for (value = low; value <= (high + DOUBLE_DRIFT_FIX); value = low + (++i * step)) {
+ Z_DVAL(tmp) = value;
+ ZEND_HASH_FILL_ADD(&tmp);
+ }
+ } ZEND_HASH_FILL_END();
} else {
+ array_init(return_value);
Z_DVAL(tmp) = low;
zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
}
@@ -1814,20 +1826,29 @@ long_str:
err = 1;
goto err;
}
- for (; low >= high; low -= lstep) {
- Z_LVAL(tmp) = (zend_long)low;
- zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
- }
+ array_init_size(return_value, ((low - high) / lstep) + 1);
+ zend_hash_real_init(Z_ARRVAL_P(return_value), 1);
+ ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) {
+ for (; low >= high; low -= lstep) {
+ Z_LVAL(tmp) = (zend_long)low;
+ ZEND_HASH_FILL_ADD(&tmp);
+ }
+ } ZEND_HASH_FILL_END();
} else if (high > low) { /* Positive steps */
if (high - low < lstep || lstep <= 0) {
err = 1;
goto err;
}
- for (; low <= high; low += lstep) {
- Z_LVAL(tmp) = (zend_long)low;
- zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
- }
+ array_init_size(return_value, ((high - low) / lstep) + 1);
+ zend_hash_real_init(Z_ARRVAL_P(return_value), 1);
+ ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) {
+ for (; low <= high; low += lstep) {
+ Z_LVAL(tmp) = (zend_long)low;
+ ZEND_HASH_FILL_ADD(&tmp);
+ }
+ } ZEND_HASH_FILL_END();
} else {
+ array_init(return_value);
Z_LVAL(tmp) = (zend_long)low;
zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
}
@@ -1835,7 +1856,6 @@ long_str:
err:
if (err) {
php_error_docref(NULL, E_WARNING, "step exceeds the specified range");
- zval_dtor(return_value);
RETURN_FALSE;
}
}