Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Example Analysis of PHP Kernel

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

Editor to share with you the example analysis of the PHP kernel, I believe that most people do not know much about it, so share this article for your reference, I hope you can learn a lot after reading this article, let's learn about it!

As a simple and powerful language, PHP can provide many language features suitable for Web. Starting from practice and following the exploration of the principle of weakly typed variables, this article continues to lead you to an in-depth understanding of the php kernel.

Recently, when communicating with a netizen, he asked me a very strange question. That is, in an operation, after adding a reference, it is found that the performance is ten thousand times slower. In my mind, references are a very error-prone problem, especially references in PHP, which have a lot of traps. Because, I have studied this piece of PHP source code before, so I can clearly parse what the reference is all about. I hope that after reading my article, I can thoroughly understand this problem. If you have any questions or questions you want to know, you can leave me a message.

Let's take a look at a piece of code:

Class RefferTest {private $data; private $testKey; function _ construct () {$key = "hello"; $this- > data [$key] = range (0, 10000); $this- > testKey = $key;} function reffer ($key) {$reffer = & $this- > data [$key]; return count ($reffer);} function noreffer ($key) {return count ($this- > data [$key]);} function test () {$T1 = microtime (true); for ($I = 0; $I

< 5000; $i++) { $this->

Reffer ($this- > testKey);} $T2 = microtime (true)-$T1; var_dump ("reffer:". Round ($T2, 4); $T1 = microtime (true); for ($I = 0; $I

< 5000; $i++) { $this->

Noreffer ($this- > testKey);} $T2 = microtime (true)-$T1; var_dump ("noreffer:". Round ($T2, 4);}} $test = new RefferTest (); $test- > test ()

If you finish this code and can say that the performance of reffer and noreffer will be 10, 000 times worse, then there is no need to read on. This blog is aimed at a novice to PHP. You can run this code for a try, it's ten thousand times worse. Of course, the code of the problem encountered by that netizen is more complex than the above, and the above code is specially simplified in order to illustrate the problem. You may have seen the problem in the code, but as to why. I think it is still necessary to analyze it. In this way, you won't make the same mistake when using PHP in the future.

In order to reduce replication, PHP adopts a copy on writer mechanism. I think this is a very common mechanism, and you must have heard of it. For example, the implementation of gcc's stl string uses such a mechanism that string assignments are not really copied, and they are copied only when they are modified. Let's start with the simplest example:

$a = str_repeat ("",); $b = $a; $a [] = ""

$an is a very large string, and if you copy it when $b = $a, it will cost a lot of memory and cpu, which is very uneconomical, in case, the following code does not change $an and $b, then copying is not necessary. Of course, $an is modified later, and at this point, it must be copied, otherwise it will be illogical. But now the question is, how do you know that when you modify $a, you have to have such a tag to copy it? The method is to use reference counting. Reference counting is also used for memory management.

The basic process is as follows:

1: create a variable that can hold a string of 10000 zeros.

2: create a variable symbol a that refers to the variable. Note that variable symbols and variables are not the same thing, the two are separate.

If you look at it from a C language perspective, PHP probably does something like this:

Char * varname = "a"; size_t varname_len = strlen (varname); zend_hash_add (EG (active_symbol_table), varname, varname_len +, & var, sizeof (zval*), NULL)

Active_symbol_table is a symbol table of PHP. All accessible variables are in this table. It is a hash table. The variable var holds the string of 10000 zeros. And it is the structure of zval. The structure of zval is as follows:

Typedef struct _ zval_struct {zvalue_value value; zend_uint refcount; zend_uchar type; zend_uchar is_ref;} zval;typedef union _ zvalue_value {long lval; double dval; struct {char * val; int len;} str; HashTable * ht; zend_object_value obj;} zvalue_value

Zvalue_value is a union that holds long, double, strings, PHP Array, and objects. That is, all types of PHP. Zval is actually for zvalue_value, adding three functions: type type, reference is_ref and reference count refcount. This is the normal variable in PHP. If you use PHP to do larger things, you will find that the memory footprint is very large. It is because one of his variables is not the one in the traditional C language, it adds a lot of things.

All right, the first sentence is finished, and here is the second sentence. The second sentence is very simple, will generate a new variable symbol b, add it to active_symbol_table, but will not add a new variable, but just, refcount++. The assignment is complete. As shown in the figure:

First of all, we should note that a, b is just a symbol, it is a key in the active_symbol_table table, and there is a pointer to a zval, so an and b are identical at the C language level. We get the first law of PHP variables:

The first law of PHP variables: if two variables point to the same zval, then the two variables are indistinguishable. That is, any operation on an is symmetrical relative to b. The symmetry here is understood in this way. It's you in the mirror, not the same. For example, if an is assigned to a, a produces copy. Similarly, if you assign a value to b, you will do the same thing, that is, b produces a copy. In other words, an and b behave the same way.

The third sentence, when writer occurs, PHP will determine whether the refcount is greater than 2, if it is greater than 2, then copy the zval, and then put the original zval refcount--. This is what copy on writer is all about, you must feel that you are very familiar with all this, you know all about it.

However, PHP is not just as simple as copy on writer, it also has a referencing problem. Introduce the concept of reference, so that the problem becomes a little more complicated. Because, referring to this tag, it means that when you writer, you don't have to copy it. In this way, the original variable is modified. In terms of the philosophy we used to learn at school, this is a pair of contradictions. They are opposing and unified, and each has its own use. As the saying goes, what exists is reasonable.

OK, let's take a look at this pair of contradictions. We only consider the situation of two combinations. Many combinations are similar. In the case of the two combinations, the assignment comes first and the reference comes after.

Or the reference comes first and the assignment comes after. We will discuss it separately, let's take a look at it first: that is, the case in which the assignment comes first and the quote comes later.

$a =; $b = $a; $c = & $a

$b = $a, which is the assignment of the copy on writer behavior. While $c and $an are reference assignments. We assume that in the above case, we can use a zval representation, that is, there is no need to copy, then the situation goes like this:

According to our first law of PHP variables, that is to say, the operation of aformab is symmetrical, but it is very obvious that there is a copy behavior for b operation, but not for an operation, and the operation behavior is different, which contradicts the first law. That is to say, if there is no contradiction in the above operation, it must be separated. The principle of separation is that whoever creates contradictions replicates. Obviously the third sentence, $c = & $a; is creating contradictions. Therefore, the copy process of internal variables is shown in the following figure:

The above case is the case where the assignment comes first and the reference comes after. In another case, the reference comes before the assignment:

$a =; $b = & $a; $c = $a

According to the first law of the PHP variable, the law must be separated in order to ensure the correctness of the law. It can be found that b and an are obviously a group of people, that is, the operations of b and an are symmetrical, they can point to the same zval, but the behavior of c is not the same as that of amemb, and changing c needs to be copied. Seeing here, I think, if you understand it, why the two count of the code posted at the beginning are so different, you should also understand. When I discussed with that netizen, it finally said, in that case, the PHP design is not good, I can completely, $c do not copy, wait for c to be write, then copy. It seems that to understand something is still a very difficult thing, think about the first law of PHP. You can assume that without separation, c points to the same zval, so the behavior of c is the same as that of is_ref b, so c will not copy. The last internal implementation can be shown in the following figure:

I used to confuse this quote, but now you can use that first law to analyze all the situations. I will write some articles on PHP kernel analysis in the future. If you want to learn more about some aspects of PHP, you can leave me a message.

Finally, it is also a hidden mistake.

Function count_bigarray () {global $bigarray; return count ($bigarray);}

Here, no reference is shown, but there is a reference hidden here. PHP automatically creates a code that references the global variable $bigarray, which is very slow if you use count here. It is best to reference it directly through the $GLOBAL array.

These are all the contents of the article "sample Analysis of the PHP Kernel". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report