Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
For some reason a blank drupal install uses this function on the icon 'misc/favicon.ico'. When using xdebug tracing I saw preg_match was called 346 times in this function. This is because this loop is done through an array with all known extensions:
foreach ($mapping as $ext_preg => $mime_match) {
if (preg_match('!\.(' . $ext_preg . ')$!i', $filename)) {
return $mime_match;
}
}
The patch changes this to a lookup instead of a loop which is quite some faster:
$last_dot = strrpos($filename, '.');
if ($last_dot !== FALSE) {
$ext = drupal_strtolower(drupal_substr($filename, $last_dot+1, drupal_strlen($filename)-$last_dot));
if (isset($mapping[$ext])) {
return $mapping[$ext];
}
}
Comment | File | Size | Author |
---|---|---|---|
#7 | 473652-optimize-file-get-mimetype.patch | 42.11 KB | Damien Tournoud |
#3 | mapping.patch | 1.69 KB | catch |
file_get_mimetype_loop.patch | 661 bytes | R.Muilwijk | |
Comments
Comment #2
catchI posted #473632: file_get_mimetype() is slow almost simultaneously which has the hack of moving that mimetype first in the loop (and benchmarks showing that it's faster).
If we can fix those fails this would be a committable solution.
Comment #3
catchOK so there's a few problems with this:
1. The mimetype mapping uses multipe extensions for array keys separated with pipes - so isset() won't work - hence those test faisl.
2. Finding the last dot in the filename won't work for "pcf.Z" extensions (and nor will strtolower).
So we have a couple of options:
1. run the isset first, then do the loop with preg_match() as fallback
2. Put commonly used mimetypes early in the array.
If we go for #1, the we should use http://uk3.php.net/manual/en/function.strrchr.php and drupal_substr() - a bit more concise that way.
Attaching my hack (option #2) from the other issue since that fixes the critical path performance issue even if it doesn't scale to other extensions.
Comment #4
Damien Tournoud CreditAttribution: Damien Tournoud commentedI'll work on something.
Comment #5
R.Muilwijk CreditAttribution: R.Muilwijk commented@catch, hmmz forgot to run the tests because simpletest didn't install.
@all, maybe we should also have a look at some cleaner solutions then using the extension. What about a solution like:
This would remove the need for using extension based mime types locally and fix the preg_match()'es though two file call's aren't fast either but at least a lot cleaner!
Comment #6
catchR.Muilwijk - can you work up a patch for yours? Let's see how it works, and benchmark it.
Comment #7
Damien Tournoud CreditAttribution: Damien Tournoud commentedThe attached patch uses a more efficient mapping strategy, and move the default mapping to a separate file. When the mapping is overridden, there is no point in loading the large default mapping.
Comment #8
catchThis saves us the 5ms on every page load.
It removes array keys like
'ps|ai|eps' => 'application/postscript',
so we don't need to do string parsing on hundreds of items.And it comes with a test.
RTBC.
Comment #9
Dries CreditAttribution: Dries commentedCommitted to CVS HEAD.
Comment #10
drewish CreditAttribution: drewish commentedi can see the rationale behind this change but i gotta say this seems pretty hacky especially when the time comes to add new mimetypes like in: #370958: FLV Flash Video Mimetypes
edited to use the correct issue number
Comment #12
aaron CreditAttribution: aaron commentedRe-opening per #531476: Add favicon mimetype theme setting, as we probably want to roll this one back once that goes in. I figure it's easier to use the original issue so we have the discussion going into this. If anyone objects, we can start a new issue instead.
Comment #13
catchThe theme setting patch is in. As long as this function stays outside the critical path, I think it'd be alright to put it back how it was.
Comment #14
catchNo longer a performance issue.
Comment #15
Damien Tournoud CreditAttribution: Damien Tournoud commented