diff --git a/includes/module.inc b/includes/module.inc
index ae772ff..9a0bd9c 100644
--- a/includes/module.inc
+++ b/includes/module.inc
@@ -948,8 +948,14 @@ function drupal_alter($type, &$data, &$context1 = NULL, &$context2 = NULL) {
       // For multiple hooks, we need $modules to contain every module that
       // implements at least one of them.
       $extra_modules = array();
+      // Store the implementations in an array index because isset() is way
+      // faster than in_array().
+      $implementations[$hook] = array_flip($modules);
       foreach ($extra_types as $extra_type) {
-        $extra_modules = array_merge($extra_modules, module_implements($extra_type . '_alter'));
+        $hook = $extra_type . '_alter';
+        $extra_implementations = module_implements($extra_type . '_alter');
+        $extra_modules = array_merge($extra_modules, $extra_implementations);
+        $implementations[$hook] = array_flip($extra_implementations);
       }
       // If any modules implement one of the extra hooks that do not implement
       // the primary hook, we need to add them to the $modules array in their
@@ -963,12 +969,13 @@ function drupal_alter($type, &$data, &$context1 = NULL, &$context2 = NULL) {
         // know whether it has any particular implementation, so we need a
         // function_exists().
         $function = $module . '_' . $hook;
-        if (function_exists($function)) {
+        if (isset($implementations[$hook][$function])) {
           $functions[$cid][] = $function;
         }
         foreach ($extra_types as $extra_type) {
-          $function = $module . '_' . $extra_type . '_alter';
-          if (function_exists($function)) {
+          $hook = $extra_type . '_alter';
+          $function = $module . '_' . $hook;
+          if (isset($implementations[$hook][$function])) {
             $functions[$cid][] = $function;
           }
         }
