The one sentence takeaway: Class constants may be quicker, but memory probably won't matter, and using the Dependency Injection Design Pattern will be more memory efficient and flexible.
While a class constant or static property will be faster than creating an array in a function (see bwoebi's answer) because it's built in memory once and can be accessed multiple times, it is in no way the most efficient method available, or the recommended way to solve the root problem the OP is aiming to solve.
If you are certain that no data is ever going to change in the future, or you're never going to want to use different sets of data at different times, even for testing, then you may be able to get away with this method anyway. If you want more flexible code, class constants or static properties can cause some serious problems. As I'll explain later, the amount of memory used or saved is unlikely to matter. More important considerations are:
- How easy is it going to be to modify my code in the future?
- How flexible is my code to changing circumstances
- How easy is it to unit test my code?
Before committing to the most memory efficient route, be sure to balance other forms of efficiency, such as efficiency of your time in developing and debugging.
#Why Memory may not matter
Due to the speed of modern computers, the performance hit you experience between the two versions should rarely make a difference. Disk I/O is more often an issue than memory. If your server is operating on a VERY small amount of memory and you expect very high volume, then the memory efficiency of your code will be more important than if you have moderate volume and moderate memory.
To put things in perspective, see this article on efficiency of arrays in PHP. The takeaway? Even though PHP5 arrays are horribly inefficient, even an array of 100,000 integers will take up about 14M. That's a LOT, but considering that the average PHP script has a memory limit of 128M, and the minimum server recommendations call for about 2 GB of memory, this suddenly looks different.
That means that you should worry about this if the rest of your code is inefficient, or you have high volume compared to low memory. That will cause your application to slow down and/or your system to crash.
Regardless, in a situation where you're exploring architectural choices from the beginning, I would strongly recommend a design pattern. Namely, the Dependency Injection design pattern. This is for a number of reasons, including code flexibility and unit testing, but also has a friendly memory footprint. Because of this, it would probably be considered best practices over either of the two options you are recommending.
##Why not static properties
At the outset the easiest route is to use static properties. However, in my experience, the easiest route is not always the best route, and can frequently be the hardest to maintain. One problem here is that your functions/methods will probably be calling another class within. As an example, let's create two classes: MyFooClass
and DoStuff
, and see how they might interact by default.
class MyFooClass
{
public static $Ms = array(82, 83, 84, 104, 106, 107, 109, 140, 190);
public static $Gs = array(0, 1, 20, 21, 28, 90, 91, 92);
public static $Ts = array(0, 1);
}
class DoStuff
{
public function oneOfThousands()
{
$array = MyFooClass::$Gs;
//... do stuff
}
}
Now, if you ever want to insert different array values for different purposes, or you want to unit test with fewer or more settings, complications abound.
###Dependency Injection to the Rescue!
Like all design patterns, Dependency Injection solves a problem. In this case, the problem is easily and efficiently passing values between multiple functions/methods without sacrificing flexibility. Using a basic DI pattern, you can get your arrays initialized in non-static properties and pass a single object containing this array property to every part of your code. That would allow you to eliminate your concern about performance.
Example:
class MyFooClass
{
private $Ms, $Gs, $Ts;
public function __construct()
{
$this->Ms = array(82, 83, 84, 104, 106, 107, 109, 140, 190);
$this->Gs = array(0, 1, 20, 21, 28, 90, 91, 92);
$this->Ts = array(0, 1);
}
public function checkFileGcodeFormat()
{
if (
!(
$this->hasM()
&& $this->hasNoXYZ()
&& in_array($this->M, $this->Ms)
)
||
(
$this->hasG()
&& in_array($this->G, $this->Gs)
)
||
(
$this->hasT()
&& $this->hasNoXYZ()
&& in_array($this->T, $this->Ts)
)
)
return false;
else
return true;
}
}
// DI here:
$foo = new MyFooClass();
$bar = new MyBarClass();
$bar->setArrays($foo);
//alternative DI approach - parameters in constructor
$bar = new MyBarClass($foo);
In your MyBarClass
, you are assigning a MyFooClass
object to a property $foo
. You can then call any public method or property from this object with $this->foo
. For example: $this->foo->checkFileGcodeFormat()
.
With this design pattern:
- When you want to develop a new unit test, it will be much easier to do so.
- If you ever want/need to implement a subset of Gcodes for an application, just pass a different object with different array values.
- Similarly, if you want to test a new Gcode on a new class without introducing it to every part of your script, you can.
- The memory expended is the size of a pointer in PHP (which is same as the size of a pointer in C... 8 bytes in a 64 bit architecture).
##Conclusion
- If you can, I would recommend using the Dependency Injection Design Pattern.
- You can choose a static property for a better memory footprint (note: This is not mutually exclusive of Dependency Injection, but is less important if you use Dependency Injection).
- In a standard web server setup, with moderate traffic, it is unlikely your memory consumption will matter, whether you use static properties or call an array from within a function.