Should ActiveRecord instances be singletons ?

This is probably something that was discussed or thought about when AR were designed.

Would is mess upp the design was changed so that find functions were made to return singletons now ?

So that $a and $b would have the same instance when this was done:

$a = Contact::model()->findByPk(1);

$b = Contact::model()->findByPk(1);

That would make sense, if you had multiple objects (inside relations, etc, …) - and changed one, then you wouldn't have old data in one of them.

It's not a performance issue, since returning a reference to a object must be cheaper than recreating it!

This is costly. It means internally we need to mainly a big table of AR instances indexed by their PKs. It also has some side-effects, although it solves some other problems that you mentioned.

For objects fetched by eager loading, they are not duplicated, though.

I don't think is really that costly.  The table we need to maintain might be 'big', but it's full of references, not a copy of AR object itself.

I did some modifications on CActiveRecord and CActiveFinder to implement this, will post them on yii google gode page in just a few secs.

Ran test on quite a big PostgreSQL table table, 33.000 rows and 36 columns.

*** SVN 1.0 branch, umodified ***

Mem: 199423 KB, Real: 297728 KB

Time: 36.679 sec

*** With the patches that implement the global storage ***

Mem: 199444 KB, Real: 297728 KB

Time: 35.659 sec

Mem = memory_get_usage()/1024, Real = memory_get_usage(true).

Now, It wasn't s huge table, but working with 33.000 Active Records in one go it not a common situation.

Results: Global caching used 21 KB more of memory, but it was about 1 sec quicker.

I didn't time the eager loading, but would expect similar results.

I'd vote for this method to be implemented into Yii :slight_smile:

>For objects fetched by eager loading, they are not duplicated, though.

Not within the same 'node', but something like:

$all = $MyAR->model()->with('order', 'manager')->findAll();

would duplicate a the same $person if they were relations both in order and manager.

$myAr->order->person and $myArr->manager->person could be referencing the same person, but the objects would be duplicated in memory.

This new method of caching objects would also prevent that.

See http://code.google.c…s/detail?id=289 for patch.

We had a similar design with the very original AR in Prado, the pattern is known as Identity Map (http://martinfowler.com/eaaCatalog/identityMap.html). This gave rise to many subtle design problems than it was worth, especially when related objects becomes involved.

Thanks for the input Wei.

Could you give an example of such problem, or link to a thread which such problem is mentioned ?