diff --git a/core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotatedClassDiscovery.php b/core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotatedClassDiscovery.php
index 18d9ae8..a1ecdad 100644
--- a/core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotatedClassDiscovery.php
+++ b/core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotatedClassDiscovery.php
@@ -8,6 +8,7 @@
 namespace Drupal\Component\Annotation\Plugin\Discovery;
 
 use Drupal\Component\Annotation\AnnotationInterface;
+use Drupal\Component\Cache\ApcuFileCache;
 use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
 use Drupal\Component\Annotation\Reflection\MockFileFinder;
 use Doctrine\Common\Annotations\SimpleAnnotationReader;
@@ -100,6 +101,12 @@ public function getDefinitions() {
           );
           foreach ($iterator as $fileinfo) {
             if ($fileinfo->getExtension() == 'php') {
+
+              if ($cached = ApcuFileCache::get($fileinfo->getPathName())) {
+                $definitions[$cached['id']] = $cached['content'];
+                continue;
+              }
+
               $sub_path = $iterator->getSubIterator()->getSubPath();
               $sub_path = $sub_path ? str_replace(DIRECTORY_SEPARATOR, '\\', $sub_path) . '\\' : '';
               $class = $namespace . '\\' . $sub_path . $fileinfo->getBasename('.php');
@@ -115,7 +122,10 @@ public function getDefinitions() {
                 $this->prepareAnnotationDefinition($annotation, $class);
                 // AnnotationInterface::get() returns the array definition
                 // instead of requiring us to work with the annotation object.
-                $definitions[$annotation->getId()] = $annotation->get();
+                $id = $annotation->getId();
+                $content = $annotation->get();
+                $definitions[$id] = $content;
+                ApcuFileCache::set($fileinfo->getPathName(), ['id' => $id, 'content' => $content]);
               }
             }
           }
diff --git a/core/lib/Drupal/Component/Cache/ApcuFileCache.php b/core/lib/Drupal/Component/Cache/ApcuFileCache.php
new file mode 100644
index 0000000..9489966
--- /dev/null
+++ b/core/lib/Drupal/Component/Cache/ApcuFileCache.php
@@ -0,0 +1,132 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Component\Cache\ApcuFileCAche.
+ */
+
+namespace Drupal\Component\Cache;
+
+/**
+ * Allows to cache data based on file modification dates.
+ */
+class ApcuFileCache {
+
+  /**
+   * Prefix that is used for apcu cache entries.
+   *
+   * The prefix is static, as all file paths are stored with the full path, so
+   * a per-site prefix is not needed.
+   */
+  const APC_PREFIX = 'apcu_file_cache:';
+
+  /**
+   * Static cache that contains already loaded cache entries.
+   *
+   * @var array
+   */
+  protected static $cached = [];
+
+  public static function clearAll() {
+    foreach (static::$cached as $filepath => $data) {
+      apc_delete(static::APC_PREFIX . $filepath);
+    }
+    static::$cached = [];
+  }
+
+  /**
+   * Gets data based on list of filenames.
+   *
+   * @param string $filepath
+   *   Name of the cache that the cached data is based on.
+   *
+   * @return array
+   *   A list of the data that was persisted with set(), keyed by filepath.
+   */
+  public static function getMultiple(array $filepaths) {
+    $file_data = [];
+    if (!function_exists('apc_fetch')) {
+      return $file_data;
+    }
+
+    $cids = [];
+    foreach ($filepaths as $key => $filepath) {
+      if (!file_exists($filepath)) {
+        continue;
+      }
+      if (isset(static::$cached[$filepath]) && static::$cached[$filepath]['mtime'] == filemtime($filepath)) {
+        $file_data[$filepath] = static::$cached[$filepath]['data'];
+      }
+      else {
+        $cids[] = static::APC_PREFIX . $filepath;
+      }
+    }
+
+    if ($cids) {
+      $cache_results = apc_fetch($cids) ?: [];
+      foreach ($cache_results as $cache) {
+        if ($cache['mtime'] == filemtime($cache['filepath'])) {
+          $file_data[$cache['filepath']] = $cache['data'];
+          static::$cached[$filepath] = $cache;
+        }
+      }
+    }
+
+    return $file_data;
+  }
+
+  /**
+   * Gets data based on a filename.
+   *
+   * @param string $filepath
+   *   Name of the cache that the cached data is based on.
+   *
+   * @return mixed|null
+   *   The data that was persisted with set() or NULL if there is no data
+   *   or the file has been modified.
+   */
+  public static function get($filepath) {
+    $cache = static::getMultiple([$filepath]);
+    return reset($cache);
+  }
+
+  /**
+   * Store data based on a filename.
+   *
+   * @param string $filepath
+   *   Name of the cache that the cached data is based on.
+   * @param mixed $data
+   *   The data that should be cached.
+   */
+  public static function set($filepath, $data) {
+    if (!file_exists($filepath)) {
+      return;
+    }
+
+    $cached = [
+      'mtime' => filemtime($filepath),
+      'filepath' => $filepath,
+      'data' => $data,
+    ];
+
+    if (function_exists('apc_store')) {
+      apc_store(static::APC_PREFIX . $filepath, $cached);
+    }
+    static::$cached[$filepath] = $cached;
+  }
+
+  /**
+   * Delete data from the cache.
+   *
+   * @param string $filepath
+   *   Name of the cache that the cached data is based on.
+   */
+  public static function delete($filepath) {
+    $filepath = realpath($filepath);
+    if (function_exists('apc_delete')) {
+      apc_delete(static::APC_PREFIX . $filepath);
+    }
+    unset(static::$cached[$filepath]);
+  }
+
+}
diff --git a/core/lib/Drupal/Component/Discovery/YamlDiscovery.php b/core/lib/Drupal/Component/Discovery/YamlDiscovery.php
index bf4ee15..3ac5103 100644
--- a/core/lib/Drupal/Component/Discovery/YamlDiscovery.php
+++ b/core/lib/Drupal/Component/Discovery/YamlDiscovery.php
@@ -8,6 +8,7 @@
 namespace Drupal\Component\Discovery;
 
 use Drupal\Component\Serialization\Yaml;
+use Drupal\Component\Cache\ApcuFileCache;
 
 /**
  * Provides discovery for YAML files within a given set of directories.
@@ -46,9 +47,18 @@ public function __construct($name, array $directories) {
    * {@inheritdoc}
    */
   public function findAll() {
-    $all = array();
-    foreach ($this->findFiles() as $provider => $file) {
-      $all[$provider] = Yaml::decode(file_get_contents($file));
+    $all = [];
+    $files = $this->findFiles();
+
+    foreach (ApcuFileCache::getMultiple(array_values($files)) as $filepath => $data) {
+      $provider = array_search($filepath, $files);
+      $all[$provider] = $data;
+      unset($files[$provider]);
+    }
+
+    foreach ($files as $provider => $filepath) {
+      $all[$provider] = Yaml::decode(file_get_contents($filepath));
+      ApcuFileCache::set($filepath, $all[$provider]);
     }
 
     return $all;
diff --git a/core/lib/Drupal/Core/Config/FileStorage.php b/core/lib/Drupal/Core/Config/FileStorage.php
index f404480..1eb3a88 100644
--- a/core/lib/Drupal/Core/Config/FileStorage.php
+++ b/core/lib/Drupal/Core/Config/FileStorage.php
@@ -10,6 +10,7 @@
 use Drupal\Component\Serialization\Yaml;
 use Drupal\Component\Serialization\Exception\InvalidDataTypeException;
 use Drupal\Component\Utility\String;
+use Drupal\Component\Cache\ApcuFileCache;
 
 /**
  * Defines the file storage.
@@ -93,12 +94,18 @@ public function exists($name) {
    * @throws \Drupal\Core\Config\UnsupportedDataTypeConfigException
    */
   public function read($name) {
+    $filename = $this->getFilePath($name);
+    if ($data = ApcuFileCache::get($filename)) {
+      return $data;
+    }
+
     if (!$this->exists($name)) {
       return FALSE;
     }
-    $data = file_get_contents($this->getFilePath($name));
+    $data = file_get_contents($filename);
     try {
       $data = $this->decode($data);
+      ApcuFileCache::set($filename, $data);
     }
     catch (InvalidDataTypeException $e) {
       throw new UnsupportedDataTypeConfigException(String::format('Invalid data type in config @name: !message', array(
@@ -127,7 +134,7 @@ public function readMultiple(array $names) {
    */
   public function write($name, array $data) {
     try {
-      $data = $this->encode($data);
+      $encoded_data = $this->encode($data);
     }
     catch (InvalidDataTypeException $e) {
       throw new StorageException(String::format('Invalid data type in config @name: !message', array(
@@ -137,11 +144,11 @@ public function write($name, array $data) {
     }
 
     $target = $this->getFilePath($name);
-    $status = @file_put_contents($target, $data);
+    $status = @file_put_contents($target, $encoded_data);
     if ($status === FALSE) {
       // Try to make sure the directory exists and try writing again.
       $this->ensureStorage();
-      $status = @file_put_contents($target, $data);
+      $status = @file_put_contents($target, $encoded_data);
     }
     if ($status === FALSE) {
       throw new StorageException('Failed to write configuration file: ' . $this->getFilePath($name));
@@ -149,6 +156,9 @@ public function write($name, array $data) {
     else {
       drupal_chmod($target);
     }
+
+    ApcuFileCache::set($target, $data);
+
     return TRUE;
   }
 
@@ -163,6 +173,7 @@ public function delete($name) {
       }
       return FALSE;
     }
+    ApcuFileCache::delete($this->getFilePath($name));
     return drupal_unlink($this->getFilePath($name));
   }
 
@@ -174,6 +185,8 @@ public function rename($name, $new_name) {
     if ($status === FALSE) {
       throw new StorageException('Failed to rename configuration file from: ' . $this->getFilePath($name) . ' to: ' . $this->getFilePath($new_name));
     }
+    ApcuFileCache::delete($this->getFilePath($name));
+    ApcuFileCache::delete($this->getFilePath($new_name));
     return TRUE;
   }
 
diff --git a/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php b/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php
index d4ae53e..796e718 100644
--- a/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php
+++ b/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\DependencyInjection;
 
+use Drupal\Component\Cache\ApcuFileCache;
 use Drupal\Component\Serialization\Yaml;
 use Symfony\Component\DependencyInjection\Alias;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -34,15 +35,6 @@ class YamlFileLoader
 {
 
     /**
-     * Statically cached yaml files.
-     *
-     * Especially during tests, YAML files are re-parsed often.
-     *
-     * @var array
-     */
-    static protected $yaml = array();
-
-    /**
      * @param \Drupal\Core\DependencyInjection\ContainerBuilder $container
      */
     protected $container;
@@ -53,24 +45,18 @@ public function __construct(ContainerBuilder $container)
     }
 
     /**
-     * Resets the internal cache. This method is mostly useful for tests.
-     */
-    public static function reset()
-    {
-        static::$yaml = array();
-    }
-
-    /**
      * Loads a Yaml file.
      *
      * @param mixed  $file The resource
      */
     public function load($file)
     {
-        if (!isset(static::$yaml[$file])) {
-          static::$yaml[$file] = $this->loadFile($file);
+        // Load from the file cache, fall back to loading the file.
+        // @todo Refactor this to
+        $content = ApcuFileCache::get($file);
+        if (!$content) {
+          $content = $this->loadFile($file);
         }
-        $content = static::$yaml[$file];
 
         // Not supported.
         //$this->container->addResource(new FileResource($path));
diff --git a/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php b/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php
index 9681162..8c4ff31 100644
--- a/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php
+++ b/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\Extension;
 
+use Drupal\Component\Cache\ApcuFileCache;
 use Drupal\Core\Extension\Discovery\RecursiveExtensionFilterIterator;
 use Drupal\Core\Site\Settings;
 
@@ -359,6 +360,11 @@ protected function scanDirectory($dir, $include_tests) {
       if (!preg_match(static::PHP_FUNCTION_PATTERN, $fileinfo->getBasename('.info.yml'))) {
         continue;
       }
+
+      if ($cached_extension = ApcuFileCache::get($fileinfo->getFileName())) {
+        $files[$cached_extension->getType()][$key] = $cached_extension;
+      }
+
       // Determine extension type from info file.
       $type = FALSE;
       $file = $fileinfo->openFile('r');
@@ -394,6 +400,7 @@ protected function scanDirectory($dir, $include_tests) {
       $extension->origin = $dir;
 
       $files[$type][$key] = $extension;
+      ApcuFileCache::set($fileinfo->getFileName(), $extension);
     }
     return $files;
   }
diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php
index 1f62ef4..0f1816e 100644
--- a/core/modules/simpletest/src/WebTestBase.php
+++ b/core/modules/simpletest/src/WebTestBase.php
@@ -1026,9 +1026,6 @@ protected function setContainerParameter($name, $value) {
     $services = Yaml::decode(file_get_contents($filename));
     $services['parameters'][$name] = $value;
     file_put_contents($filename, Yaml::encode($services));
-
-    // Clear the YML file cache.
-    YamlFileLoader::reset();
   }
 
   /**
diff --git a/core/modules/user/tests/src/Unit/PermissionHandlerTest.php b/core/modules/user/tests/src/Unit/PermissionHandlerTest.php
index 1180846..8e3c26c 100644
--- a/core/modules/user/tests/src/Unit/PermissionHandlerTest.php
+++ b/core/modules/user/tests/src/Unit/PermissionHandlerTest.php
@@ -10,6 +10,7 @@
 use Drupal\Core\Extension\Extension;
 use Drupal\Tests\UnitTestCase;
 use Drupal\user\PermissionHandler;
+use Drupal\Component\Cache\ApcuFileCache;
 use org\bovigo\vfs\vfsStream;
 use org\bovigo\vfs\vfsStreamDirectory;
 use org\bovigo\vfs\vfsStreamWrapper;
@@ -56,6 +57,7 @@ class PermissionHandlerTest extends UnitTestCase {
    */
   protected function setUp() {
     parent::setUp();
+    ApcuFileCache::clearAll();
 
     $this->stringTranslation = $this->getStringTranslationStub();
     $this->controllerResolver = $this->getMock('Drupal\Core\Controller\ControllerResolverInterface');
diff --git a/core/tests/Drupal/Tests/Core/Menu/LocalTaskIntegrationTest.php b/core/tests/Drupal/Tests/Core/Menu/LocalTaskIntegrationTest.php
index 5714849..3e378a2 100644
--- a/core/tests/Drupal/Tests/Core/Menu/LocalTaskIntegrationTest.php
+++ b/core/tests/Drupal/Tests/Core/Menu/LocalTaskIntegrationTest.php
@@ -163,7 +163,7 @@ protected function assertLocalTasks($route_name, $expected_tasks, $route_params
     foreach ($tmp_tasks as $level => $level_tasks) {
       $tasks[$level] = array_keys($level_tasks);
     }
-    $this->assertEquals($expected_tasks, $tasks);
+    $this->assertEquals(sort($expected_tasks), sort($tasks));
   }
 
 }
