Which is more performant: entity_metadata_wrapper or field_get_items? To get values from entities, there are two ways:


Use field_get_items and get the value of a field
Use entity_metadata_wrapper and get the value of a field


Although entity_metadata_wrapper abstracts away the language differences, its API is still awkward sometimes, especially when using PHP 5.3. For example, getting the value of a long text field usually goes this route:

$field = $wrapper-&gt;field-&gt;value();
print $field['safe_value'];


Fortunately, PHP 5.4 supports this syntax: print $wrapper-&gt;field-&gt;value()['safe_value'];.

But my question is more concerned about performance. How do they both work? Do they query the database every time they request a value? Does entity_metadata_wrapper requests everything at once? (Making field_get_item more suited to single-value-retrievals.)

I'm not brave enough to dive deep into Drupal source.
The short answer: field_get_items() is more performant than entity_metadata_wrapper().

Check out the code for these functions:


field_get_items()
entity_metadata_wrapper()


Both require that you pass along the entity, which has already been loaded from the database. For example:

$node = node_load(123);
$items = field_get_items('node', $node, 'field_my_field_name');
print $items[0]['value'];


or, as you've already suggested:

$wrapper = entity_metadata_wrapper('node', $node);
$field = $wrapper-&gt;field_my_field_name-&gt;value();
print $field['safe_value'];


Both of these instances kind of bother me because of the silly logic in trying to get a value that's already available to you, but they are certainly useful in lots of cases.

You could just do print $node-&gt;field_my_field_name[LANGUAGE_NONE][0]['value']; but that would throw PHP notice errors if the field doesn't have a value, since you're trying to access arrays that may not exist (i.e. [LANGUAGE_NONE][0]['value']). I find myself doing this quite often lately:

if ($field = field_get_items('node', $node, 'field_my_field_name')) {
  print $field[0]['value'];
}


which is a lot cleaner than doing:

if (isset($node-&gt;field_my_field_name[LANGUAGE_NONE]) &amp;&amp; isset($node-&gt;field_my_field_name[LANGUAGE_NONE][0])) {
  print $node-&gt;field_my_field_name[LANGUAGE_NONE][0]['value'];
}


If you look at the code for field_get_items()) you'll see that it's doing nothing more then ensuring that the field's array has data in the curent language and then returns it. So, the overhead of running such a tiny function is negligible, but if you are really concerned with performance you can just do your own check if the data exists and then print it.

Edit: Since field_get_items() runs field_language() there would actually be a bigger performance hit than just checking the language, so, if you already know that $entity->language exists, you could just write your own super-performant function:

function my_super_performant_field_value_getter($entity, $field_name) {
  return isset($entity-&gt;{$field_name}[{$entity-&gt;language}]) ? $entity-&gt;{$field_name}[{$entity-&gt;language}] : FALSE;
}