Looking through core cachegrinds, I noticed that every call to drupal_render() calls drupal_process_attached() and drupal_process_states() - these functions then only operate if (!empty($elements['#attached/states'])).

Since those functions are almost exclusively called by drupal_render(), apart from the one place where drupal_add_library() sets #attached itself then calls drupal_process_attached() immediately afterwards, it makes sense to move the if statement into drupal_render() itself, and save ourselves a couple hundred function calls on most pages.

I don't expect this to have any effect in benchmarks, maybe a tiny one with micro benchmarking, but neither can it cause any harm, and it removes profiler noise.

CommentFileSizeAuthor
drupal_render.patch2.06 KBcatch
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

moshe weitzman’s picture

IMO, this adds noise for people who read drupal_render(). Also, it isn't really drupal_render()'s business to write that condition. That belongs in the process function IMO. Unless benchmarks prove we want this, I vote a small -1.

Most profiler reports like webgrind let you omit functions that take less than x% of request time so I bet the profiler noise issue is easily mitigated.

catch’s picture

I did microbenchmarks before/after and there's no measurable difference - at least not with a basic array('#prefix' => 'foo', '#markup' => 'foo', '#suffix' => foo), so this is purely a matter of taste.

However if we followed this pattern everywhere, all our functions would have if (empty($var)) { return; } up top - I think it's better for the caller to be responsible. I also think we have to get out of this mindset of "it's just an extra function call" for critical path functions - look at the check_plain() issue.

moshe weitzman’s picture

Why would we gum up every caller when we can only gum up the function which actually has the knowledge of whats supposed to be empty. Putting the empty inside the function is better encapsulation. Seems to me that empty inside the function improves readability and encapsulation.

In my taste, we only have to get out of that mindset when benchmarks make it worthwhile. Otherwise, readability prevails.

We're at a stalemate. Need more opinions.

And, many many thanks for working on performance.

chx’s picture

There is no benefit and it violates encapsulation.

Crell’s picture

Except that we have many other instances where moving a check outside of a function gives us a small boost. We even just committed one: #619566: Don't invoke hook_url_outbound_alter() if there's nothing to invoke

chx’s picture

Status: Needs review » Reviewed & tested by the community

OK, I am convinced

  if (isset($elements['#cache'])) {
    drupal_render_cache_set($prefix . $elements['#children'] . $suffix, $elements);

that's the same. drcs starts with a huge if and could do this check but we decided to check in drupal_render instead. That seems to be a pattern in drupal_render anyways even if the other property checks are not performance. It's not something I would be happy to do in other places but drupal_render already has this "if property call function" pattern.

casey’s picture

Issue tags: +Performance

added tag

catch’s picture

Issue tags: -Performance

Don't mean to play tag pong, but there's zero measurable performance impact here, so trying to keep the performance queue tidy.

webchick’s picture

Status: Reviewed & tested by the community » Fixed

I went ahead and committed this. It seems like it cleans the code up slightly, though I know Moshe isn't nuts about it. chx points out that this is consistent with how we handle this in other places.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.