简体   繁体   中英

Does using static methods and properties in PHP use less memory?

I'm working on a web application that sees dozens of concurrent users per second. I have a class that will be instantiated many times within the same page load. In that class, I have some properties that will always be the same across every object, so I'm thinking about declaring these properties as static in an effort to reduce the memory that will be used when multiple instances of this class are instantiated during the same page request.

Will doing this use less memory for this application because PHP can store the value of the static properties only once? Will doing this save memory across concurrent users, or just within each PHP process?

How does this work for methods? If this means objects can recycle the same methods, then why wouldn't all methods of a class be declared static if you are trying to save on memory?

I don't feel entirely comfortable with why and when one would declare a property or method static, but I do understand that declaring them as static allows them to be accessed without instantiating an object of the class ( this feels like a hack... these methods and properties should be somewhere else... no? ). I'm specifically interested in the way a static declaration affects memory usage in an effort to keep memory usage as low as possible on my web server... and in general so I have a better understanding of what is going on.

When you declare a class method/variable as static, it is bound to and shared by the class, not the object. From a memory management perspective what this means is that when the class definition is loaded into the heap memory, these static objects are created there. When the class's actual object is created in the stack memory and when updates on the static properties are done, the pointer to the heap which contains the static object gets updated. This does help to reduce memory but not by much.

From a programming paradigm, people usually choose to use static variables for architectural advantages more than memory management optimization. In other words, one might create static variables like you mentioned, when one wants to implement a singleton or factory pattern. It provides more powerful ways of knowing what is going on at a "class" level as opposed to what transpires at an "object" level.

Look static vs singleton tests: http://moisadoru.wordpress.com/2010/03/02/static-call-versus-singleton-call-in-php/

Note: for some reasons, stackoverflow didn't show multilne topic, so i'm adding a picture.

Number of runs  Singleton call time (s)     Static call time (s)
100             0.004005                    0.001511
1,000           0.018872                    0.014552
10,000          0.174744                    0.141820
100,000         1.643465                    1.431564
200,000         3.277334                    2.812432
300,000         5.079388                    4.419048
500,000         8.086555                    6.841494
1,000,000       16.189018                   13.696728

Checkout more details here: https://stackoverflow.com/a/3419411/260080

Does using static methods and properties in PHP use less memory?

Probably. But, why would you mess with your OOP architecture?

Does it matter?

Probably not. What takes memory is PHP itself. I firmly think removing a few bytes because you use static methods will not make a difference. Instead, don't load useless modules. Ex if you don't use GD, don't load it. Activate caching to reduce the number of times PHP is called.

Generally, yes. Static methods and properties use less memory. However, the difference is very small.

The more interesting thing is the performance difference between static and non-static methods .

Static method calls are faster over many iterations, but static methods don't really save memory.

If the class you are declaring doesn't have any properties that need to be unique to each object instance, then you could declare every method and property as static. If, however, you have properties that need to be bound to each object, then static methods are not helpful. The reason is because inside static methods, there is no reference to $this so you cannot reference object properties from static methods.

Read up on the Static Keyword for a better understanding of this.

I just improved the benchmark of Stanislav's link to have it live:

https://3v4l.org/rDpVv

Results for PHP 7.4.1:

Runs by case: 500000 
Memory usage at start: 426,320

Run                                 Duration    %       Memory
Dynamic                             0.0594      30%     496
Dynamic instantiated                0.0917      46%     0           #
Dynamic instantiated stored         0.1994      100%    48,967,472  # slowest
Storage only                        0.0422      21%     16,781,392
Cost of instations only when stored 0.1572      79%     32,186,O8O  # cost of stored instatiations minus storage cost (diff of 2 previous lines)
Static                              0.0870      44%     0           # equivalent to dynamic with instantiation
Singletons with many getInstance    0.1213      61%     376
Singletons with one getInstance     0.0669      34%     320         # equivalent to "Dynamic"
Functions assigning $GLOBALS        0.0605      30%     0           # more than 2 times longer than using "global"
Functions assigning a global        0.0458      23%     32          # fastest. 32bits allocated? probably passed by copy... odd
Functions with $counter by ref      0.0707      35%     0           # slow for functions
Functions with $counter static prop 0.0524      26%     0

Remarks:

  • "Functions modifying a global" is the fastest with 23%
  • "Instantiate, store then calling a dynamic method" is the longest so 100%
  • Storing instances cost a lot of memory and 21% of the total time
  • "Passing $counter as parameter by ref" is almost 2 times longer than "Functions modifying a global"
  • Calling a function modifying a static property is super fast, almost a half of calling a static method. Funny
  • MyClass::call() costs 75% of the time of Singleton::getInstance()->call() but 133% of $mySingleton->call()
  • MyClass::call() costs as much as (new MyClass)->call()
  • "Static" is equivalent in cost to "dynamic instatiated non stored". Really interesting!

Conclusions on dev practices (valid in jan 2020):

  • Never use $GLOBALS, 'global $myVar' is super fast (and allocates 32 bits?)
  • Programming with global variables and functions only is the fastest PHP possible? Old school rocks!
  • Storing an instance for a lot of method calls then drop it is optimal.
  • Avoid to store a lot of instances.
  • "Instantiating for calling" and "Static calls" have the same cost

Cheers

PS: I cannot do more runs due to limitations even if the results are not 100% stable (I'm seen 20% variations on some refresh of the full bench) PS 2: if you want to disable the cache of 3v4l.org just add a space in the code wherever you want

I'm not an expert in memory management of PHP, but I would say you DON'T save much. If and how much you save depends on some aspects:

  • The size of the object (when you create an instance, how much other data does the object hold).
  • The number of objects you create.

Especially the number of objects is important. If you have only one instance, you save 50%. In this case:

Case A - Static: You don't instantiate the object, but just use the class definition, which is stored in the memory. But the class definition is loaded for every REQUEST, which means you have the same amount of class definitions in the memory as you have concurrent requests.

Case B - Instances: Additionally to case A you also have an instance of this object for each request, thus double the memory usage for this part of you software.

Finally: if it is easier for you to work with static parameters instead of instantiating the class every time, you should go with the static way. But don't expect too much of a memory boost.

If you share the data use a static. It's faster and saves you the process of object instantiation. Singletons win versus statics when you need a single entry point. I covered this on my blog about 1 week ago.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM