I would like to ask about the performance and memory usage of instantiating an object in php.
On every php file of my application, i included a file which connect to the database.
$db->DB::getInstance();
$db->connect('all my credentials');
This is the getInstance() function in my db class.
//singleton database instance
public static function getInstance() {
if (!self::$Instance) {
self::$Instance = new DB();
}
return self::$Instance;
}
Currently everything turns out well. But i am concern of performance issues as in, can it be improved, possbile flaws etc.
I researched and found out that singleton instance can help to save memory. It will reuse the object if it's already been instantiate. Am i right?
My exact question is
E.g. if i have 10 users accessing the script, does it means that the object will be instantiate 10 times? When that happens, will it put 10 x load on my memory usage? -> this is pretty what i am interested in
Appreciate any expert advice.
As with all performance tweaking, you should measure what you're doing instead of just blindly performing some voodoo rituals that you don't fully understand. When you save an object in $_SESSION, PHP will capture the objects state and generate a file from it (serialization). Upon the next request, PHP will then create a new object and re-populate it with this state. This process is much more expensive than just creating the object, since PHP will have to make disk I/O and then parse the serialized data. This has to happen both on read and write.
In general, PHP is designed as a shared-nothing architecture. This has its pros and its cons, but trying to somehow sidestep it, is usually not a very good idea.
Do not use Singleton's, it makes testing a hell.
Objects are sent around the system in PHP as references by default. So you can simply share that Database connection object around other classes in the system without performance hit (it won't clone them until you specifically order it to be cloned).
But yes, if ten users use your system then that means you will have ten instances of that class. And it means that memory usage is ten times higher IF all the requests of users are active at the same time (well, usually, depending on load and server settings, some requests may have to wait until others are complete).
It is possible to tell PHP and database to use persistent connections, which means that other scripts that use the same database username and password and connect to the same database, share the 'connection'. But this is almost never recommended, since requests from one user may slow down the experience of another user who has to wait while the previous users database query has completed.
So, in short, do not use Singletons. In a smart object-oriented architecture, the class is passed to child objects or inherited from parents. This means that the class can easily be changed or a mockup can be easily created for testing purposes.
Related
I have an application in which I repeatedly use the same (big) class. Since I use AJAX for that App, I always have to create a new object of this class. Someone advised me to cache an instance of this class and use it whenever it is required (using apc in a php environment)
What are the benefits of it ? is it really saving some time ?
$this->tickets_persist = unserialize(#apc_fetch("Tickets"));
if (!$this->tickets_persist) {
$this->tickets_persist = new Tickets_Persistance(); // Take long time
apc_store("Tickets", serialize($this->tickets_persist));
}
The benefits are only really realized if you are dealing with a class that has an expensive instantiation cost. If there is things that take a lot of time, memory or other resource being done in the constructor of the class (for example: reading an XML sitemap and building a complex data structure to build your navigation.) you can dodge this by leveraging caching.
It's also worth noting that resources (like database links and such) are not able to be cached and they would have to be re-established after the object is unserialized (here is where the __sleep and __wakeup magic method comes in).
It would only be worth it if your object requires a lot of processing during instantiation. Caching will not help you with "big" objects, it will help you when you want to avoid processing that can be repeated. In your case, it would only be worth it if your construct method required a lot of processing. Let's take an example of how caching would work in the context of a webpage :
On first page load, instantiate and cache the object for x hours
On any subsequent page load for the next x hours, it will directly return the object, without processing the instantiation
After x hours, the cached object will be expired, the next page load will re instantiate the object and re cache it
Your application will behave in the same way, the only difference is that you will "re-use" the instantiation process that has already been done.
I've been looking for an answer on this, so far I have been unable to find an answer. My question is; What is the best way to store a huge global class that does not require any dynamic input, it only needs to be used once.
Lets take for example a template class:
<?php
class Design_API{
function loadfile($file){
//load file here
}
// do file manipulation here
function presentfile(){
echo($this->file);
}
}
?>
Utilizing this class as a basic example of a layout. What would be the best way performance and security wise to use it. Would it be to create an instance of it as a global; store the instance in a session; or simply make it a static class.
Also, say we used a session if 2 clients access the site at the same exact millisecond, would php lock the session file forcing client 2's web load to take longer?
This question is a bit too mixed up to be answered in a consistent way, so here are some points:
one client does not block another, unless they're accessing a shared resource
sessions are not shared resources between different users, forget about this misconception
wherever you store objects hardly makes a difference in performance
it makes even less of a difference between different requests and users, since no resources are shared between requests
code what you mean first and what is most maintainable, optimize this for performance later when it is proven to be slow (which it likely won't be)
avoid globals wherever possible
don't store stuff in the session that does not belong there, like code
avoid static classes as much as possible, they cause code coupling, which should be reduced
static classes are not necessarily faster
The best way to handle this is to make the class a Singleton class and use the static method to instatiante it.
Storing the object in session will involve serialization and de-serialization which is very bad for performance. Also if you store any resources in the class they can't be serialized.
In PHP 5.2.x, mySQL 5.x
Im having a bit of an issue wrapping my head around what should and should not be an instance of a class in php because they are not persistent once the page is rendered.
Say I have a list of comments. To me, it would make sense that every comment be its own object because I can call actions on them, and they hold properties. If I was doing this in another language (one that has persistent state and can be interacted with), I would do it that way.
But it seems wasteful because to do that I have a loop that is calling new() and it would probably mean that I need to access the database for each instance (also bad).
But maybe im missing something.
Php just seems different in how I think about class and objects. When should something be a class instance, and when not?
This is a subjective issue, so I'll try to gather my thoughts coherently:
Persistence in PHP has sort of a different meaning. Your thinking that each comment should be an object because comments have actions which can be performed on them seems correct. The fact that the objects won't persist across a page load isn't really relevant. It isn't uncommon in PHP to use an object in one script, which gets destroyed when the script completes, and then re-instantiate it on a subsequent page load.
Object-oriented programming provides (among other things) code organization and code reuse. Even if an object is only really used once during the execution of a script, if defining its class aids in program organization, you are right to do so.
You usually needn't worry about resource wastefulness until it starts to become a problem; if your server is constantly taxed to where it degrades your user experience or limits your expansion, then it is time to optimize.
Addendum:
Another reason defining a class for your comments is that doing so could pay dividends later when you need to extend the class. Suppose you decide to implement something like a comment reply. The reply is itself just a comment, but holds some extra attributes about the comment to which it refers. You can extend the Comment object to add those attributes and additional functionality.
Unless you count QBASIC back when I was a kid, I learned to program in the object oriented paradigm a half-decade ago in university, so I understand how it works. I have difficulty, however, implementing it in my large, database-driven PHP applications, because everything is re-initialized on each page load. The only true persistence is the database, but pulling all the data from the database and reconstructing all the objects on every page load sounds like a lot of overhead for not much benefit, as I'll just have to do it all over again on next page load.
Additionally, I run into these sorts of problems when I try to re-factor an application (third attempt now) to OO:
A class called "Person" exists, and it contains a variety of properties. One of the extensions of that class, "Player", contains a "parent" property, of the type "Player". Initially, none of the players start with any parents, so they would all be initialized with that field as NULL. Over time, however, parents would be added to the Players properties, and would reference other Player objects that already exist.
In PHP, however, it's inevitable that I would have to rebuild the class structure with Players already having parents. In such a case, if I instantiate a Player who has as a parent a Player that hasn't been instantiated yet - I have a problem.
Is it necessary to reduce the scope of OO programming when dealing with PHP?
You're confusing OOP concepts, with concepts about HTTP and persistence.
Your question isn't really about OOP at all- it's about persisting OOP data across multiple HTTP requests.
PHP doesn't automatically persist objects across HTTP requests- it's left up to you to take care of that (in your case, doing just as you said: "pulling all the data from the database and reconstructing all the objects on every page load").
Is it necessary to reduce the scope of OO programming when dealing with PHP?
No. You just need to use lazy loading to instantiate parent player only if it becomes necessary.
Class Player {
protected $id;
protected $name;
protected $parentId;
protected $parent;
public static function getById($id) {
// fetch row from db where primary key = $id
// instantiate Player populated with data returned from db
}
public function getParentPlayer() {
if ($this->parentId) {
$this->parent or $this->parent = Player::getById($this->parentId);
return $this->parent;
}
return new Player(); // or null if you will
}
}
This way if you intantiate player id 40:
$john = Player::getById(40);
It does not have the $parent property populated. Only upon call to getParentPlayer() it is being loaded and stored under that property.
$joe = $john->getParentPlayer();
That is of course only if $parentId is pointing to non-NULL.
Update: to solve problem of duplicate instances stored in protected property when two or more players share single parent, static cache can be used:
protected static $cache = array();
public static function getById($id) {
if (array_key_exists($id, self::$cache)) {
return self::$cache[$id];
}
// fetch row from db where primary key = $id
// instantiate Player populated with data returned from db
self::$cache[$id] = ... // newly created instance
// return instance
}
If you expect to access significant number of parents on every request, it may be feasible to select all records from database at once and store them in another static pool.
Items not being created by means of parents is indeed something that is tricky. You could do something like, ID referencing and build a PlayerManager that does the linking for you. By means of RUID's (Runtime Unique ID's). But of course, you would like to have the parents be created first.
So when creating something like an OO structure of your database, which I would encourage if you want to do some extra manipulations on it besides printing. It is doable to create a player from your DB and then, if it has a parent, create the parent as you would do normally. When arriving at the parent in your while-loop. You can just say, no it is already created. Use a Player-manager class for this, which holds your Players. So it can check if Players (and thus parents) are already there.
So you get a bit of a different way of walking through your DB, instead of just doing it linear.
As for: is it necessary to do so. I actually don't know that much about it myself. It seems, as far as I've seen on the web, that PHP classes are mostly used to created one object that can do smart things (like a DOMDocument).
But do you really have to convert your DB table to objects? It depends on your type of application. If printing is what you want, it doesn't seem logical. If some big manipulation with a lot of calls to the objects (or normally to the table), I maybe would like to see a nice OO programmed structure.
OOP programming in PHP is for me more a way of having a good maintainability and a good architecture (composition, factories, component based programing, etc ).
For sure you'll need to rethink some Design Patterns used in persitent envirronments. Pools of objects, etc. And of course some Design Patterns as still completly good in PHP used in short-term module in apache: Singleton, Factory, Adapter, Interfaces, Lazy loading etc.
About the persitence problem there're several solutions. Of course database storage. But you have as well the session storage and application caches (like memcached or apc). You can store serialized objects in such caches. You'll just need a good autoloader to get the classes loaded (and a good opcode to avoid re-interpreting the sources at every requests).
Some objects are really heavy to load and build, we can think for example of an ACL object, loading roles, ressources, default policy, exception rules, maybe even compling some of theses rules. Once you've got it it would be a desaster to rebuild this object at every request. You should really study the way to store/load this finished object somewhere to limit his load time (avoiding SQL requests and build time). Once built it's certainly an object that could have a long life, like 1hour.
The only objects that you cannot store as serialized strings are in fact the one which depends shortly of data updates by concurrent requests. Some websites does not even need to really care about it, accuracy of data is not the same in a public website publishing news and in a financial accouting app. If your application can handle pre-build serialized objects you can see the serialize-storage-load-unserialize as a simple overhead in the framework :-) But effectivly, share nothing, no object listening to all concurrent requests, no write operation on an object shared with a parallel request until this object (or related data) is stored somewhere (and read). Take it as a challenge!
Is it considered better practice and/or more efficient to create a 'reset' function for a particular object that clears/defaults all the necessary member variables to allow for further operations, or to simply construct a new object from outside?
I've seen both methods employed a lot, but I can't decide which one is better. Of course, for classes that represent database connections, you'd have to use a reset method rather than constructing a new one resulting in needless connecting/disconnecting, but I'm talking more in terms of abstraction classes.
Can anyone give me some real-world examples of when to use each method? In my particular case I'm thinking mostly in terms of ORM or the Model in MVC. For example, if I would want to retrieve a bunch of database objects for display and modify them in one operation.
When you re-use the objects, you're using the Object Pool pattern.
One of the main issues to consider is is how much state these objects have, and how much of that state needs to be reset for the next user. With a database connection, you don't want to have to do the connection again - otherwise you might as well just create a new one. The idea is to leave the object connected, but to clear any results.
Reasons not to use object pool:
Complexity of the pool
Memory cost of having these objects instantiated when not required. This might even slow down garbage collection.
Establishing exactly what state needs to be reset
Reasons to use an object pool:
It takes too long to create or destroy an object
Further details in a paper by Kircher and Jain.
Reseting is done for performance reasons. Default approach is to create new object when you need it, not recycle some existing one. If you are not worrying about your php being slow than just create. If you worry about php being slow, you should stop and worry about other things you rely on being much slower.