]> granicus.if.org Git - php/commitdiff
Optimized array_slice
authorXinchen Hui <laruence@php.net>
Fri, 16 Jan 2015 09:54:50 +0000 (17:54 +0800)
committerXinchen Hui <laruence@php.net>
Fri, 16 Jan 2015 09:54:50 +0000 (17:54 +0800)
ext/standard/array.c

index ae56fd4957b218ea700f1cd0f2da6175e157dfd2..5662dee8ff12a8a5c16daba858cd8daab50d52cd 100644 (file)
@@ -2367,26 +2367,43 @@ PHP_FUNCTION(array_slice)
 
        /* Start at the beginning and go until we hit offset */
        pos = 0;
-       ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(input), num_key, string_key, entry) {
-               pos++;
-               if (pos <= offset) {
-                       continue;
-               }
-               if (pos > offset + length) {
-                       break;
-               }
+       if (!preserve_keys && (Z_ARRVAL_P(input)->u.flags & HASH_FLAG_PACKED)) {
+               zend_hash_real_init(Z_ARRVAL_P(return_value), 1);
+               ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) {
+                       ZEND_HASH_FOREACH_NUM_KEY_VAL(Z_ARRVAL_P(input), num_key, entry) {
+                               pos++;
+                               if (pos <= offset) {
+                                       continue;
+                               }
+                               if (pos > offset + length) {
+                                       break;
+                               }
+                               ZEND_HASH_FILL_ADD(entry);
+                               zval_add_ref(entry);
+                       } ZEND_HASH_FOREACH_END();
+               } ZEND_HASH_FILL_END();
+       } else {
+               ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(input), num_key, string_key, entry) {
+                       pos++;
+                       if (pos <= offset) {
+                               continue;
+                       }
+                       if (pos > offset + length) {
+                               break;
+                       }
 
-               if (string_key) {
-                       entry = zend_hash_add_new(Z_ARRVAL_P(return_value), string_key, entry);
-               } else {
-                       if (preserve_keys) {
-                               entry = zend_hash_index_add_new(Z_ARRVAL_P(return_value), num_key, entry);
+                       if (string_key) {
+                               entry = zend_hash_add_new(Z_ARRVAL_P(return_value), string_key, entry);
                        } else {
-                               entry = zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), entry);
+                               if (preserve_keys) {
+                                       entry = zend_hash_index_add_new(Z_ARRVAL_P(return_value), num_key, entry);
+                               } else {
+                                       entry = zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), entry);
+                               }
                        }
-               }
-               zval_add_ref(entry);
-       } ZEND_HASH_FOREACH_END();
+                       zval_add_ref(entry);
+               } ZEND_HASH_FOREACH_END();
+       }
 }
 /* }}} */