Encountering PHP's In_array low performance issues

Source: Internet
Author: User
Tags php source code zend ibm developerworks

PHP's performance has been improving. However, if the use of inappropriate, or a inattention, still may be stepping on the internal implementation of PHP hole. I ran into a performance problem a few days ago.

PHP's performance has been improving. However, if the use of inappropriate, or a inattention, still may be stepping on the internal implementation of PHP hole. I ran into a performance problem a few days ago.

The thing is this, a colleague feedback our interface each return takes 5 seconds, we review the code together, "surprise" discovery actually in the loop (about 900 times) called a read cache operation, and this cache key does not change, so we put this code to the outside of the loop , re-test, interface return time dropped to 2 seconds, alas! It's a 1 time-fold increase, but it's obviously not the result we can accept!
The amount of code that has a performance problem is not large, we have eliminated the IO problem, wrote a test code, and sure enough, the problem quickly reappears.


<?php
$y = "1800";
$x = Array ();
for ($j =0; $j <2000; $j + +) {
$x []= "{$j}";
}

for ($i =0; $i <3000; $i + +) {
if (In_array ($y, $x)) {
Continue
}
}
?>



shell$ time/usr/local/php/bin/php test.php 

Real 0m1.132s 
User 0m1.118s 
SYS 0m0.015s 

Yes, we're using a string-type number, and that's what you get out of the cache! So here's a deliberate turn into a string (if it's a number, it doesn't happen, and you can verify it yourself). You can see the time spent 1 seconds, only 3,000 cycles, the back of the SYS time is also doomed to use strace will not get any valid information.  

shell$ strace-ttt-o xxx/usr/local/php/bin/php test.php 
shell$ less xxx 



We only see the delay between the two system calls is very large, but do not know what to do? Helpless, fortunately, Linux debugging tool in addition to Strace and Ltrace (of course, there are dtrace,ptrace, not in the scope of this article, omitted).  

Reference: Strace is used to track the situation of a process's system call or signal generation, and Ltrace is used to track the process call library functions (VIA&NBSP;IBM developerworks).  

to exclude interference, we assign the $x directly to an array ("0″," 1″, "2″,......) To avoid excessive malloc calls affecting the results. Execute  

shell$ ltrace-c/usr/local/php/bin/php test.php 

2




We see Library functions __strtol _internal call very frequent, reached 94%, too exaggerated, and then I looked at this library function __strtol_internal is what, the original is Strtol alias, Simple is to convert the string to grow plastic, It is possible to guess that the PHP engine has detected that this is a string-type number, so it is expected to compare them to the growth integer, which consumes too much time in the conversion process, and we execute it again:


shell$ ltrace-e "__strtol_internal"/usr/local/php/bin/php test.php



can easily catch a large number of such calls, to this, the problem found, In_array this loose comparison, will be two character string first converted to a long integer type and then compare, but do not know the performance of the above.



Know the crux of the problem, we solve a lot of solutions, the simplest is for In_array plus the third parameter is true, that is, to become a strict comparison, but also to compare the type, so as to avoid the PHP smart conversion type, run up really much faster, the code is as follows:


<?php
$y = "1800";
$x = Array ();
for ($j =0; $j <2000; $j + +) {
$x []= "{$j}";
}

for ($i =0; $i <3000; $i + +) {
if (In_array ($y, $x, True)) {
Continue
}
}
?>


shell$ time/usr/local/php/bin/php test.php

Real 0m0.267s
User 0m0.247s
SYS 0m0.020s



How many times faster!!! You can see that the SYS time-consuming is barely changing much. We ltrace again, or we want to assign the $x directly, excluding the disturbance of malloc invocation, because we actually pull out of the cache in the actual application, so there is no such loop in the sample code to request memory.
Execute again


shell$ ltrace-c/usr/local/php/bin/php test.php



Such as:

__ctype_tolower_loc takes up the most time! Check the library function. __ctype_tolower_loc: The simple understanding is that the string is converted to lowercase, so does this mean that the In_array comparison string is not case-sensitive? Actually this function call already and our this in_array feel contact little, about in_array realization, or go to see PHP source code, probably understand more thorough, good, can not say, welcome to communicate with me, write wrong place please many treatise.

——————— 2013.08.29 Split Line ——————————

At night, the following PHP 5.4.10 the source code, the interest of In_array is really big ah, haha, located in the./ext/standard/array.c line 1248th, you can see that he called the Php_search_array function, the following Array_ Serach is also the tune of this, only the last parameter is different! After some tracking, in the case of In_array, he finally called the function zendi_smart_strcmp (really a "smart" function) to compare, located in the./zend/zend_ OPERATORS.C, we use Ltrace to catch a lot of conversion into the integer type of operation is that is_numeric_string_ex behavior.



The function is_numeric_string_ex is in./zend/zend_ Operators.h defined in the preceding a bunch of judgments and conversions, in 232 rows called the Strtol, is the system function we mentioned in the article, the string into the growth of integer, there is a picture of the truth

Encountering PHP's In_array low performance issues

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.