Speed up the Laravel Baum package

by Marcel Pociot — on

Here's a quick tipp, if you happen to use the Laravel Baum package and you have large nested structures.

In my case, we have a hierarchy of over 1000 entries that we need to display as a JSON / Array structure.

The whole API call used to take nearly 7 seconds - so I began some detective work and fired up Blackfire to find the bottle neck.

Take a look at the following call stack:

Old call stack screenshot from Blackfire

Holy shit! That's 903.453 calls in total!

The Baum package is doing this when sorting the node hierarchy. Here's the responsible code:

uasort($dict, function($a, $b){
    return ($a->getOrder() >= $b->getOrder()) ? 1 : -1;
});

And the getOrder() method looks like this:

  /**
   * Get the model's "order" value.
   *
   * @return mixed
   */
  public function getOrder() {
    return $this->getAttribute($this->getOrderColumnName());
  }

The package is accessing the getAttribute method, which in return takes possible mutators into account.

If you run into this issue and don't need any mutators for your sort column, override the getOrder() method, to access your attributes array directly:

So in my Model file, I just modified the getOrder method to look like this:

    /**
     * Get the model's "order" value.
     *
     * @return mixed
     */
    public function getOrder() {
        return $this->attributes['sort'];
    }

This results in the new callstack:

New callstack

Yeah - the uasort closure gets called a lot of times, but this time we don't have the overhead of all the Eloquent model methods.

This gave me more than 5 seconds of speed back :)