Flourish PHP Unframework
This is an archived copy of the forum for reference purposes

fORM performance

posted by anonymous 8 years ago

I want to use fORM, but I'm curious as to how fast it is when you map a table to a class... every time the site loads, it has to describe the table, and generate the class again? How does this work? Where do you actually map the table to class, am I missing something?

Hi - it is a good question. There always some cost of this kind of abstraction.

First of all the class are not really generated, however you can choose to do so (see http://flourishlib.com/docs/fORM#DynamicfActiveRecordClasses). But you make your classes inherit from fActiveRecord.

Flourish will read the database schema upon each request. I honestly don't know the practically cost of this - but I imagine it is not cheap, and that is why is cacheable. When you go live ensure to enable db scheme caching:

fORM::enableSchemaCaching(new fCache('file', '/file/path/to/cache/file'));

(see http://flourishlib.com/docs/fORM#SchemaCaching)

From the names of tables and the foreign keys you set up. Flourish will automatically build a map of routes. So say that you wanted fetch Product with ID 1, flourish would pluralize the class name and then 'underscorize' it. Then a lookup in the map is not far from fetching the product.

$product = new Product(1);

Always when working with ORMs you should ensure to prefetch relations that you know you are going to need, so that when you iterate through you records you would not need to fire a SQL on each iteration. In flourish this is called prebuild.

// Fetch authors with last name Hebert

$authors = fRecordSet::build('Author', array('last_name=' => 'Hebert'));

// Prebuilding books = fetching all books in one SQL

$authors->prebuildBooks();

foreach ($authors as $author) {
    $books = $author->buildBooks();    // At this point no SQL is fired, read buildBooks() as getBooks() - flourish terminology.
   
    ... iterate through books
}

I hope this gave you some answers. Otherwise ask away :)

posted by mblarsen 8 years ago

If you don't use fORM::enableSchemaCaching(), there will usually end up being around 2n queries executed to introspect the database, where n is the number of tables in the database. I know on MySQL, PostgreSQL and SQLite, these queries tend to take on the order of 1/10000 of a second each. During development I usually leave fORM::enableSchemaCaching() off so that the code recognizes changes in the database structure without any work on my part. Once the site launches, I set up the caching to improve performance.

The way that all of the automatic ORM functionality works is through the fSchema class. This class inspects the database and returns information about tables, column and relationships. This database information is then used by fActiveRecord to automatically respond to unrecognized method calls. Much of the functionality is done via the PHP 5 __call magic method, which allows intercepting method calls to undefined methods. So wile the class is not regenerated on every page load, the database structure does drive the functionality. This type of dynamic programming in PHP is slower than explicitly defined methods.

You definitely can see that the ORM performs more slowly than regular SQL statements. This is due to all of the places in which it allows you to inject code and the way in which it uses introspection and reflection to provide automatic functionality.

Even having written the entire ORM I still drop back to SQL, and especially prepared statements when I need the utmost in database performance. When updating or inserting a bunch of simple records that don't have a lot of business logic in PHP, I will often user SQL queries. When I am interacting with just a few records, I find the benefits of the ORM outweigh the cost. Being able to write plugins and override methods is extremely powerful and allows saving quite a bit of development time and monotony. However, even when I use plain SQL, I always include the functionality inside of my fActiveRecord objects to keep all interaction with the database together.

All of that said, the best way to write fast code is to profile it and see where it is slow. Once you find the slow parts, spend time of rewriting it and making it faster.

posted by wbond 8 years ago