I don't have better why to rephrase the question , you might suggest me one. Most of the time I re-use a variable in php I wonder, which one will be memory/processor efficient . e.g
case A
$string_var ='1,2,4,5,6,7,8';
$array_var =explode(',',$string_var);
Case B: re-use the same variable (string variable and re-declare as array object)
$array_var ='1,2,4,5,6,7,8';
$array_var =explode(',',$array_var);
My question is not from code-readability point of view . I wonder which one will be efficient way in term of memory and processor utilization.
$string_var ='1,2,4,5,6,7,8';
$array_var =explode(',',$string_var);
This will keep both the string and the array in memory, using more memory. If you'd overwrite the original variable, the previously stored content would be garbage collected at some point, freeing up memory. In practice it may not make any real difference, since the values won't be garbage collected immediately, and if your variables are reasonably scoped they should go out of scope soon enough anyway.
It makes virtually no difference in processing time.
Go with what makes more sense logically. If you don't need $string_var anymore, there's no need to keep it around as a separate variable. Try to declutter your namespace as much as possible.
Each time you create a new variable, a bit of memory is allocated to that variable. Therefore 2 variables will take around twice as much memory. It is better to use the same variable Case B as that only uses the memory required for 1 variable.
Both of them will affect the processor in same manner. Though, there will be lower memory usage in the Case B as you'll be updating an existing variable to a new array.
If this wasn't PHP, but a "lower level" language like C, the answer would be quite simple:
will be slightly more efficient in speed (directly rewrite results to destination location in memory, skip rewriting the pointer)
will be slightly more efficient in matter of memory (temporary location holding the result between right-side and left-side of the operation deallocated immediately after operation, just one variable allocated permanently.)
With PHP being a scripted language, all I can say B might be marginally more memory-conservative in the long run, but the amount is really insignificant. Other than that, all bets are off, write a benchmark.
Related
I didn't find an answer to this (maybe wrong search), so giving the following simple example:
echo '<div><span>'. $varname .'</span></div>';
What would be the right (= faster, better from the perspective of performance or memory usage) way of doing it? Just echoing everything at once or breaking in concatenated parts, like:
$thevar = '<div><span><a href="';
$thevar .= $varlink;
$thevar .= '" rel="nofollow">';
$thevar .= $varname;
$thevar .= '</a></span></div>';
echo $thevar;
I have seen both ways around, does it make any difference?
As always, this depends on the situation you have. So, let's consider the cases:
Concatenation
echo '<div><span>'. $varname .'</span></div>';
This does a single calculation and it has no faults by itself. However, if you need to calculate this many times (outputting it in 1000 places, for instance), then you might want to store this into a variable to avoid code duplications and improve performance.
Concatenation with template
echo "<div><span>{$varname}</span></div>";
or even
echo "<div><span><a href='{$varlink}' rel='nofollow'>{$varname}</a></span></div>";
Behaves in the same way as above, but you do not have to explicitly concatenate.
Variable
$foo = '<div><span>'. $varname .'</span></div>';
echo $foo;
If you compute this into a variable and then you reuse that variable, then, if you need to get the same value repeatedly, then it's better for your performance to only compute it once and reuse the result. The caveat is that your variable is stored in memory and you need to avoid wasting performance and memory.
Conclusion
In more general terms, your question is as follows:
Is it better for performance/memory usage to compute the results of a formula and store it in a variable, or is it to be preferred that you just compute the result and pass it on
And the answer is:
if you only use the value once, then storing it into a variable as a minuscule cost in performance and memory usage (assuming that your value is not very big), because storing something takes more memory and time than not storing it, yet, this is such a small cost that you should not worry about it and if your code is more understandable with putting this into a variable, then do so
if you need to reuse this many times, then it's better to store it into a variable (again, if the value is very big, that requires separate analysis), because computing the same thing again and again is costing you in performance and duplicating code leads to inconsistencies and inconsistencies lead to bugs
if you need to reuse many huge such values many times, then you need to carefully analyze your current situation
But, everything aside, don't optimize your code before you have performance issues, because the reasons of performance issues are often different from what you perceive them to be. It's good to write high-performing code that does not use much memory, so if you know something to be quicker/smaller beforehand, use that knowledge while you write code, but don't aim for mathematical perfection of performance improvement at the time of the initial implementation of your code, because your effort is unlikely to pay off. It's possible that you will never encounter performance issues with the code you write and if you do, then it will likely be different from the one you believe it to be at some point in the future.
I have php application which should manage (export) big (huge) amount of data, and it has to be done on production... so I need to make as low memory usage as possible (main criteria).
Shortly say App exporting data in cycle, like
for($fileCounter=0;$fileCounter<=70;$fileCounter++) {
... HERE a lot of (more than 1K lines) huge work, many variables a lot of DB queries from another databases etc ...
}
I don't want to show here full logic because it can take a lot of time for other peoples, it's not the main point here.
Main point is, why if I will unset() all newly created variables during each iteration it does not decrease memory usage ? like this
for($fileCounter=0;$fileCounter<=70;$fileCounter++) {
// optimization purpose
$vars_at_start = array_keys(get_defined_vars());
echo memory_get_peak_usage(true) . PHP_EOL;
... huge logic ...
$vars_at_end = array_diff($vars_at_start, array_keys(get_defined_vars()));
foreach($vars_at_end as $v) unset($v);
unset($vars_at_end);
}
and how I could decrease memory usage ? if I need to use so many queries, variebles etc..
P.S. code is not mine :) and I don't want to rewrite it from scratch, I'm just looking for optimization direction.
without variables cleaning memory usage is next (it is measuring in the beginning of each iteration)
23592960
Started: 0 - 12:58:26
Ended: 13:00:51
877920256 (difference 854'327'296)
Started: 1 - 13:00:51
Ended: 13:03:39
1559494656 (difference 681'574'400)
and with variables cleaning
23592960
Started: 0 - 12:47:57
Ended: 12:50:20
877920256 (difference 854'327'296)
Started: 1 - 12:50:20
Ended: 12:53:16
1559756800 (difference 681'836'544)
Based on my reading PHP has a lot reason to leak memory... like this https://bugs.php.net/bug.php?id=48781
There is a tool called valgrind it can help, gone to try it :)
Although unset() does not free the memory consumed by the PHP process, it does free it for use by the PHP script itself.
So, if you are creating a variable of 10M of size 10 times in a loop and unsetting (or rewriting) it at the end of the loop, the memory consumption should be as low as 10M + all other variables by the end of the loop.
If it grows - then, there is a leak somewhere in the full logic you don't want to show.
Because PHP does it automatically.
When variable is not used any more, PHP unsets it itself.
Because unset doesn't free up memory. It merely frees the variable. But if that variable points to some sort of complex structure, that PHP's memory management can't figure out how to free up, it won't.
$vars_at_end = array_diff($vars_at_start, array_keys(get_defined_vars()));
foreach($vars_at_end as $v) unset($v);
unset($vars_at_end);
This whole block of code is working on copies (or even copies of copies) of your variables, so it's adding large amounts of memory.
All that you ever unset are the copies of copies in the foreach loop.
You need to unset the actual variables that you use
BTW, your foreach ... unset loop does nothing anyway. PHP uses a reference-based delayed copy-on write system to optimise memory use. This foreach loop this in effect a no-op. Storage is freed -- that is returned to the internal Zend Engines emalloc allocator (not to the OS) -- or reuse once the reference count for any element is zero. This will happen anyway for local variables when you leave the scope of a function and for class properties when you destroy a class object. There is no point in cloning a shallow copy of a variable and then unsetting this as this just does a +1 -1 on the reference count.
If you mine the code for the main variables used in the loop and unset them then you will truly decrement reference counts and to 0, then you will free up storage for reuse. However, as troelskyn implies, there are many ways the existing code can leave data elements with a non-zero reference. The classic way is if your code is using references than you can create cyclic reference chains which will never be reclaimed unless the cycle is explicitly broken. Even having a global array which is use to hold results can hog memory.
Sorry, but your statement:
I don't want to show here full logic because it can take a lot of time for other peoples, it's not the main point here.
is wrong. In PHP if you want to understand why you are not returning storage into the memory pool, then you must look into the code.
unset() on a variable marks it for 'garbage collection'
Have you tried __destruct() ?
http://www.php.net/manual/en/language.oop5.decon.php
First, I apologize if this just a coding style issue. I'm wondering about the pros and cons of assign a new variable for each property or function to just to re-assign an existing variable. This is assuming you don't need access to the variable beyond the scope.
Here's what I mean (noting that the names $var0,... are just for simplicity),
Option#1:
$var0= array('hello', 'world');
$var1="hello world";
$var2=//some crazy large database query result
$var3=//some complicated function()
vs.
Option#2:
$var0= array('hello', 'world');
$var0="hello world";
$var0=//some crazy large database query result
$var0=//some complicated function()
Does it depend on the memory size of the existing variable? I.e., is re-assigning memory more computationally expensive that assigning a new variable?
Is this always a scope issue, meaning you should use Option#2 only if you don't need each of the variable values outside the scope shown here?
Does it depend on what each variable value is? Does re-assigning to different data types have different costs associated with it?
Technically speaking, reusing variables would be (insignificantly) faster. It will make zero difference in measurable performance though.
While hardware gets cheaper and hours get more expensive, you should rather look to have maintainable code. This will save yourself headaches and your company hard dollars in the long run.
Only optimize where enough performance gain can be made to offset the
amount of work (money) you are putting into it.
Nowadays of clouds and server clusters, a-bit-less-optimized code will most likely not make for a slower project in the end. It is more probable that your project will run just as fast, but will take a few more cpu cycles, and therefore cost you a little bit more money to your hosting provider. This minor added cost though, will most likely not weigh up to hours of optimizing for performance gain. Unless, ofcourse, you're asking this because you're developing for Amazon. (and even at places like Amazon, with millions and millions of hits per day, reusing variables will not result any noticable performance gain)
To get back to your question; I believe you should only reuse a variable when it will hold updated content of the original state. But in general, that doesn't happen too much.
I think in the following situation, reusing the $content var is the logical choice to make
function getContent()
{
$cacheId = 'someUniqueCacheIdSoItDoesNotTriggerANotice';
$content = someCacheLoadingCall( $cacheId );
if (null === $content) {
$content = someContentGeneratingFunction();
someCacheSavingCall( $cacheId, $content);
}
return $content;
}
Descriptive code
Also, please be kind to your future self to always use descriptive names for your variables. You will thank yourself for it. When you then make the pact with yourself to never reuse variables unless it logically makes sense, you've made another step towards maintainable code.
Imagine, that in 6 months from now, after you've done another big project - or a more small projects - you get a call from an important client that there is a bug in the old project. Holy !##! Gotta fix that right now!
You open up and see functions like this everywhere;
function gC()
{
$cI = 'someUniqueCacheIdSoItDoesNotTriggerANotice';
$c = sclc( $cI );
if (null === $c) {
$c = scg_f();
scsc( $cI, $c);
}
return $c;
}
Much better to use descriptive variable and function names and to get a code editor with good code completion so you're still coding as fast as you want. Right now, I would recommend Aptana Studio or Zend Studio, Zend has a little bit better code completion, but Aptana has proven to be more stable.
PS. I don't know your level of programming, sorry if I babbled on too far. If not relevant for you, I hope to have helped someone else who might read this :)
Personally I would say you should never ever reassign a variable to contain different stuff. This makes it really hard to debug. If you are worried about memory consumption you can always unset() variables.
Also note that you should never ever have variables names $var#. Your variablenames should describe what it holds.
In the end of the day it's all about minimizing the number of WTFs inyour code. And option two is one big WTF.
Does it depend on the memory size of the existing variable? I.e., is re-assigning memory more computationally expensive that assigning a new variable?
It's about limiting the number of WTFs for both you and other people (re)viewing your code.
Is this always a scope issue, meaning you should use Option#2 only if you don't need each of the variable values outside the scope shown here?
Well if it is in a totally other scope it is fine if you use the same name multiple names. As long as it is clear what the variabel contains, e.g.:
// perfectly fine to use the same name again. I would go as far as to say this is prefered.
function doSomethingWithText($articleText)
{
// do something
}
$articleText = 'Some text of some article';
doSomethingWithText($articleText);
Does it depend on what each variable value is? Does re-assigning to different data types have different costs associated with it?
Not a matter of cost, but a matter of maintainability. Which is often way more important.
You should never use option #2. Reusing variables for unrelated blocks of code is a terrible practice. You shouldn't even be in a situation where option #2 is possible. If your function is so long that you're changing context completely and working on some different problem, you should refactor your function into smaller single-purpose functions.
You should never reuse a variable out of some desire to "recycle" them after the old value is no longer used. If a variable is no longer it should naturally fall out of scope if you're architecturing your software correctly. Your decision should have nothing to do with performance or memory-optimization, neither of which are affected by the naming of your variables. Your only consideration when picking variable names should be producing maintainable, stable code.
The fact that you're even asking yourself whether to reuse your variables means you're using names which are too generic. Variable names like var0,var1 etc are terrible. You should be naming your variables according to what they actually contain, and declaring a new variable when you need to store a new value.
I am working on website and I am trying to make it fast as much as possible - especially the small things that can make my site a little bit quicker.
So, my to my question - I got loop that run 5 times and in each time it echo something, If I'll make variable and the loop will add the text I want to echo into the variable and just in the end I'll echo the variable - will it be faster?
loop 1 (with the echo inside the loop)
for ($i = 0;$i < 5;$i++)
{
echo "test";
}
loop 2 (with the echo outside [when the loop finish])
$echostr = "";
for ($i = 0;$i < 5;$i++)
{
$echostr .= "test";
}
echo $echostr;
I know that loop 2 will increase a bit the file size and therfore the user will have to download more bytes but If I got huge loop will it be better to use second loop or not?
Thanks.
The difference is negligible. Do whatever is more readable (which in this case is definitely the first case). The first approach is not a "naive" approach so there will be no major performance difference (it may actually be faster, I'm not sure). The first approach will also use less memory. Also, in many languages (not sure about PHP), appending to strings is expensive, and therefore so is concatenation (because you have to seek to the end of the string, reallocate memory, etc.).
Moreover, file size does not matter because PHP is entirely server-side -- the user never has to download your script (in fact, it would be scary if they did/could). These types of things may matter in Javascript but not in PHP.
Long story short -- don't write code constantly trying to make micro-optimizations like this. Write the code in the style that is most readable and idiomatic, test to see if performance is good, and if performance is bad then profile and rewrite the sections that perform poorly.
I'll end on a quote:
"premature emphasis on efficiency is a big mistake which may well be the source of most programming complexity and grief."
- Donald Knuth
This is a classic case of premature optimization. The performance difference is negligible.
I'd say that in general you're better off constructing a string and echoing it at the end, but because it leads to cleaner code (side effects are bad, mkay?) not because of performance.
If you optimize like this, from the ground up, you're at risk of obfuscating your code for no perceptable benefit. If you really want your script to be as fast as possible then profile it to find out where the real bottlenecks are.
Someone else mentioned that using string concatenation instead of an immediate echo will use more memory. This isn't true unless the size of the string exceeds the size of output buffer. In any case to actually echo immediately you'd need to call flush() (perhaps preceded by ob_flush()) which adds the overhead of a function call*. The web server may still keep its own buffer which would thwart this anyway.
If you're spending a lot of time on each iteration of the loop then it may make sense to echo and flush early so the user isn't kept waiting for the next iteration, but that would be an entirely different question.
Also, the size of the PHP file has no effect on the user - it may take marginally longer to parse but that would be negated by using an opcode cache like APC anyway.
To sum up, while it may be marginally faster to echo each iteration, depending on circumstance, it makes the code harder to maintain (think Wordpress) and it's most likely that your time for optimization would be better spent elsewhere.
* If you're genuinely worried about this level of optimization then a function call isn't to be sniffed at. Flushing in pieces also implies extra protocol overhead.
The size of your PHP file does not increase the size of the download by the user. The output of the PHP file is all that matters to the user.
Generally, you want to do the first option: echo as soon as you have the data. Assuming you are not using output buffering, this means that the user can stream the data while your PHP script is still executing.
The user does not download the PHP file, but only its output, so the second loop has no effect on the user's download size.
It's best not to worry about small optimizations, but instead focus on quickly delivering working software. However, if you want to improve the performance of your site, Yahoo! has done some excellent research: developer.yahoo.com/performance/rules.html
The code you identify as "loop 2" wouldn't be any larger of a file size for users to download. String concatination is faster than calling a function like echo so I'd go with loop 2. For only 5 iterations of a loop I don't think it really matters all that much.
Overall, there are a lot of other areas to focus on such as compiling PHP instead of running it as a scripted language.
http://phplens.com/lens/php-book/optimizing-debugging-php.php
Your first example would, in theory, be fastest. Because your provided code is so extremely simplistic, I doubt any performance increase over your second example would be noticed or even useful.
In your first example the only variable PHP needs to initialize and utilize is $i.
In your second example PHP must first create an empty string variable. Then create the loop and its variable, $i. Then append the text to $echostr and then finally echo $echostr.
Can any body give me a a introduction of how to program efficiently minimizing memory usage in PHP program correctly and generate my program results using minimum memory ?
Based on how I read your question, I think you may be barking up the wrong tree with PHP. It was never designed for a low memory overhead.
If you just want to be as efficient as possible, then look at the other answers. Remember that every single variable costs a fair bit of memory, so use only what you have to, and let the garbage collector work. Make sure that you only declare variables in a local scope so they can get GC'd when the program leaves that scope. Objects will be more expensive than scalar variables. But the biggest common abuse I see are multiple copies of data. If you have a large array, operate directly on it rather than copying it (It may be less CPU efficient, but it should be more memory efficient).
If you are looking to run it in a low memory environment, I'd suggest finding a different language to use. PHP is nice because it manages everything for you (with respect to variables). But that type coersion and flexibility comes at a price (speed and memory usage). Each variable requires a lot of meta-data stored with it. So an 8 byte int (32 bit) would take 8 bytes to store in C, it will likely take more than 64 bytes in PHP (because of all of the "tracking" information associated with it such as type, name, scoping information, etc). That overhead is normally seen as ok since PHP was not designed for large memory loads. So it's a trade-off. More memory used for easier programming. But if you have tight memory constraints, I'd suggest moving to a different language...
It's difficult to give advice with so little information on what you're trying to do and why memory utilization is a problem. In the common scenarios (web servers that serve many requests), memory is not a limiting factory and it's preferable to serve the requests as fast as possible, even if this means sacrificing memory for speed.
However, the following general guidelines apply:
unset your variables as soon as you don't need them. In a program that's well written, this, however, won't have a big impact, as variables going out of scope have the same effect.
In long running scripts, with lot's of variables with circular references, and if using PHP 5.3, trey calling the garbage collector explicitly in certain points.
First of all: Don't try to optimize memory usage by using references. PHP is smart enough not to copy the contents of a variable if you do something like this:
$array = array(1,2,3,4,5,);
$var = $array;
PHP will only copy the contents of the variable when you write to it. Using references all the time because you think they will save you copying the variable content can often fire backwards ;)
But, I think your question is hard to answer, as long as you are more precise.
For example if you are working with files it can be recommendable not always to file_get_contents() the whole file, but use the f(open|...) functions to load only small parts of the file at once or even skip whole chunks.
Or if you are working with strings make use of functions which return a string offset instead of the rest of a string (e.g. strcspn instead of strpbrk) when possible.