Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Doctrine query memory usage

Doctrine appears to be taking well over 4MB of RAM to execute a single, simple query:

print memory_get_peak_usage()." <br>\n";
$q = Doctrine_Query::create()
    ->from('Directories d')
    ->where('d.DIRECTORY_ID = ?', 5);

$dir = $q->fetchOne();
print $dir['name']." ".$dir['description']."<br>\n";

print memory_get_peak_usage()." <br>\n";

/***************  OUTPUT:  **************************

6393616
testname testdescription
10999648

/***************************************************/

This is on a test database with very little data in it - the item that I am querying doesn't contain any data other than what is displayed here.

Is there potentially something wrong with the way I have the system set up, or is this standard memory usage for Doctrine?

like image 752
Fragsworth Avatar asked Sep 11 '09 19:09

Fragsworth


3 Answers

From what I can see, you code doesn't seem to be wrong...


As a test, I've set up a quick example, with a very simple table (only four fields).

Here is the relevant code :

var_dump(number_format(memory_get_peak_usage()));

$test = Doctrine::getTable('Test')->find(1);

var_dump(number_format(memory_get_peak_usage()));

When doing that, I have this kind of output :

string '1,316,088' (length=9)
string '2,148,760' (length=9)

Considering the table is really simple and that I am only fetching one line, it seems "much" to me too -- but that's quite consistent with what you are getting, and with what I saw on other projects :-(


If you only need to display your data, and not work with it (ie update/delete/...), a solution might be to not fetch complex objects, but only a simple array :

$test = Doctrine::getTable('Test')->find(1, Doctrine::HYDRATE_ARRAY);

But, in this case, it doesn't make much of a difference, actually :-( :

string '1,316,424' (length=9)
string '2,107,128' (length=9)

Only 40 KB of difference -- well, with bigger objects / more lines, it might still be a good idea...


In the Doctrine manual, there is a page called Improving Performance ; maybe it could help you, especially for these sections :

  • Conservative Fetching
  • Free Objects


Oh, btw : I did this test on PHP 5.3.0 ; maybe this can have an impact on the amount of memory used...

like image 57
Pascal MARTIN Avatar answered Nov 07 '22 10:11

Pascal MARTIN


I agree with romanb's answer - using an OpCode cache is a definite must when using large libs/frameworks.

An example related to OpCode caching

I've recently adopted Doctrine usage with Zend Framework and was curious about memory usage - so like the OP, I created a method using similar criteria to the OPs test and ran it as an overall test to see what ZF + Doctrine's peak memory usage would be.

I got the following results:

Result without APC:

10.25 megabytes
RV David
16.5 megabytes

Result with APC:

3 megabytes
RV David
4.25 megabytes

Opcode caching makes a very significant difference.

like image 40
Aries VII Avatar answered Nov 07 '22 10:11

Aries VII


Well, where does this memory usage come from? As Pascal MARTIN pointed out, array hydration does not make a great difference which is logical concerning that we're only talking about a few records here.

The memory consumption comes from all the classes that are loaded on demand through autoloading.

If you dont have APC set up, then yes, there is something wrong with the way your system is set up. Dont even start to measure performance and expect good results with any large php library without an opcode cache like APC. It will not only speed up the execution but also reduce memory usage by at least 50% on all page loads except the very first one (where APC needs to cache the bytecodes first).

And 4MB with your simple example really smells like no-APC, otherwise it would really be a bit high.

like image 4
romanb Avatar answered Nov 07 '22 11:11

romanb