Welcome Guest, Not a member yet? Register   Sign In
DataMapper & ORM performance
#1

[eluser]Vang[/eluser]
I'm currently working on a eshop platform built on CI 1.6.3. There is a system similar to DataMapper.
I'm seeing a huge rise in required resources. In particular I had to raise php's memory limit to be able to get the complete list of products (around 500 of them).

Has anyone noticed anything similar working with DataMapper or any similar ORM implementation ?
I'd like to hear your opinions on this.
#2

[eluser]quasiperfect[/eluser]
why would u want need to get 500 products in one go ?
#3

[eluser]Vang[/eluser]
So I can display them afterwards with the tablesorter jquery plugin
#4

[eluser]garymardell[/eluser]
Seems to me that you should be using pagination and using jquery to get the pages by calling sections of data as required using ajax. Unless you really need to display all 500 in one go.
#5

[eluser]Vang[/eluser]
I agree. However it's completely irrelevant to the issue of DataMapper performance.
#6

[eluser]garymardell[/eluser]
Well as it makes a new object per row its not surprising that it uses alot of memory. It looks like it was never designed for returning alot of rows. I suggest using plain queries or just active record queries for it.
#7

[eluser]ntheorist[/eluser]
@vang

i'm currently working with datamapper and i've been working on similar issues with memory consumption on large queries.

How are you loading your data into your views? When i'm working with a single Object, i typically load it directly, like
Code:
$post = new Post();
    $post->where('id',2)->get();
    $viewdata = $this->load->view('post',array('post'=>$post), TRUE);

Although yes when dealing with a large number of rows, the 'all' array can get just as large, and a lot of that has to do with the fact that each object in the array is an instance of Datamapper. If you load the all array into a view, you will be essentially copying the array of datamaps. One thing i've tried to use to sort out just the data is the _to_array() function.

Code:
$post = new Post();
    $post->get(); // get all posts
    
    foreach($post->all as $p)
    {
        $this->load->view('post',$p->_to_array());
    }

this way, you're not copying the entire instance to the view, just the data. Plus the returned array will nicely insert the variable names, so each $p->title becomes $title in your view.

Next, if you're using a template library or something that stores and 'renders' the view data, that process may also be making copies of your data, which multiplies with each row you send to it.

I struggled for a bit because i wanted to use datatables/tablesorter, but i opted to have sorting/paging done on the server side (with ajax as an option). The client side functionality is nice, but yes if your results grow to 1000+ rows etc, you'll be faced with either huge memory consumption by the sheer amount of data (at least on first run if you have caching on) and then have to resort to server side paging anyway at some point.

Lastly, i would recommend using some sort of opcode caching utility if you are not already, such as eaccellerator. I was delighted to see my scripts reduce memory consumption from 3+ megs to 500k at the flip of that switch.

cheers,

CC
#8

[eluser]m4rw3r[/eluser]
If you use _to_array(), it will duplicate all the data anyway (+ it needs parsing the object to array) as PHP does not copy object -> array by reference (I mean in the internals, arrays are copy-on-write).

So I recommend passing the objects by reference instead (default in PHP 5), as you won't create duplicate sets of data with that method.
#9

[eluser]ntheorist[/eluser]
yeah i actually switched from passing the enitre object to a 'list' view, which ran the foreach loop, and instead creating a header view and then loading a 'single item' view for each instance in the all array. I noticed my memory consumption dropped about 25% right away. The other thing is that i can reuse the 'single item' view again for other purposes. I do the same thing for form views, etc. I'm sort of building a crud style base controller for adminning datamaps and this seems the way to go so far. I don't use the _to_array() method much myself except in specific instances like copying user data to session etc. so it is handy.

Sometime it would be nice to rework datamapper for optimized usage, perhaps integrate some sort of datamap-level caching scheme. Also i wonder if storing the validation/model config externally would help, i separated the validtion into its own class and it helps memory consumption quite a bit when not needed (read vs write) plus it cleans up the code
n
#10

[eluser]tdktank59[/eluser]
Check out DMZ

the newest version has some caching, I have no idea how much it helps but its bound to do something...




Theme © iAndrew 2016 - Forum software by © MyBB