Re: oop too slow
| From: | Krzysztof Gorzelak | Date: | Thu, 19 Aug 2004 22:09:47 +0000 |
| Subject: | Re: oop too slow | ||
| References: | 1 | Groups: | php.general |
| Request: | Send a blank email to php-general+get-194292@lists.php.net to get a copy of this message | ||
U¿ytkownik "Jason Davidson" <jdavidson@zworg.com> napisa³ w wiadomo¶ci
news:21634.1092935386@zworg.com...
> When i have many many objects of the same type to build, i do something
> like this...
>
> function getEvents($sql = '') {
> $events = $this->dbh->query("
> SELECT cols, cols, FROM table,table
> WHERE blah blah balh ($sql ? " AND $sql" : ''),'rows_array');
>
> $rv = array();
> foreach($events as $event) {
> $rv[] = new CalendarEvent($event);
> }
>
> return $rv;
> }
>
> my event class takes an array of data and uses phps list function to
> load its members. In this case, i save 100s and 100s of queries ,
> using just 1. Its a massive improvment if it fits your scheme. To get
> one event, i create a method called getEvent($id) that is a wrapper to
> getEvents, and only uses the first record.. of coarse, there is only
> one record.. but ya.. cheers
>
> Jason
>
> Marcus Bointon <marcus@synchromedia.co.uk> wrote:
> >
> > on 19/8/04 9:49, Krzysztof Gorzelak at krzysztof@uno.pl wrote:
> >
> > > Hi
> > > I'm trying my new php5 script, but it takes about 1.2s to generate my
page.
> > > That is, how my oop model looks like :
> > >
> > > [category]
> > > | | |
> > > [photo] [desc] [products]
> > >
> > >
> > > [products]
> > > |
> > > [product]
> > > | | |
> > > [photo] [desc] [keys]
> > >
> > >
> > > [keys]
> > > |
> > > [key]
> > > |
> > > [values]
> > > |
> > > [value]
> > >
> > > Each object gets data from mysql by itself. The generation time of 1
> > > category [30 products, 10 keys, 5 values ~= 300 mysql queries] takes
as I
> > > said more than a 1s (on quite fast machine). How can this model be
improved?
> > > Do I create too many objects ? What are the oop solutions for such
problem ?
> >
> > This is something that I've wrestled with too. If you make each item you
> > deal with a clean, self-sufficient object, with self-storage, data
hiding
> > etc, it is inevitable that you run into this problem. It is a symptom of
a
> > fundamental clash between Relational DB and OO points of view. The only
> > trick I have found to work around it that is OO-clean is to use factory
> > methods or objects that create multiple objects from a single DB query,
so
> > as well as having a 'get' method that populates an object from a DB,
make
> > another means of creating an object from local data that has been
obtained
> > from a larger query that returned sufficient values to populate multiple
> > items.
> >
> > > I also use an extra table to create many-to-many relation betwean a
product
> > > and a key. Is this the only way in mysql ?
> > >
> > > [product]
> > > |
> > > [product_id, key_id]
> > > |
> > > [key]
> >
> > Yes, that's the correct way to represent a M:M relation in a relational
DB.
> > The join table is an artefact of a relational model, rather than an OO
one,
> > so the answer is to hide the existence of this table within the objects
at
> > either end - so have product and key objects, but not product_key
objects.
> > Each object should have a method that retrieves instances of all the
related
> > objects of the other kind. This is really a different manifestation of
the
> > first problem.
> >
> > Ultimately the trick is to create separate factory objects or
higher-level
> > methods inside the existing objects that can create multiple instances
from
> > a single database query. Having said that, it's difficult to spot the
best
> > places to do this. For example, you might normally create multiple
product
> > objects from an array of database IDs like so:
> >
> > foreach($productids as $id)
> > $products[] = new product($id);
> >
> > You can see that this would cause a query for each instantiation.
> >
> > With a product factory class, you might do this instead:
> >
> > $products = product_factory::get($productids);
> >
> > Which achieves the same result, but using only a single DB query (hidden
> > inside the factory class, which does NOT call the product class in the
same
> > way!). The next problem is keeping your product_factory and product
classes
> > in sync - I'm sure there must be a nice pattern to deal with that
somewhere.
> >
> > Marcus
> > --
Thanks a lot, after your replies I made a little google search on 'factory
class' and found a great article:
http://www.phppatterns.com/index.php/article/articleview/49/1/1/.
My objects
are still too slow (0,3s) but now I'm going to try Advanced PHP Debugger.
Krzysztof Gorzelak