diff --git a/core/lib/Drupal/Component/Cache/ApcuFileCache.php b/core/lib/Drupal/Component/Cache/ApcuFileCache.php
new file mode 100644
index 0000000..0567a65
--- /dev/null
+++ b/core/lib/Drupal/Component/Cache/ApcuFileCache.php
@@ -0,0 +1,149 @@
+<?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 = [];
+
+  /**
+   * The cache context.
+   *
+   * @var string
+   */
+  protected $context;
+
+  /**
+   * Constructs an ApcuFileCache object.
+   *
+   * @param string $context
+   *   A context to ensure that the same files could be cached for different
+   *   purposes without clashing.
+   */
+  public function __construct($context) {
+    $this->context = $context;
+  }
+
+  /**
+   * 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 function get($filepath) {
+    $filepaths = [$filepath];
+    $cached = $this->getMultiple($filepaths);
+    return isset($cached[$filepath]) ? $cached[$filepath] : NULL;
+  }
+
+  /**
+   * Gets data based on filenames.
+   *
+   * @param string[] $filepaths
+   *   List of file names used as cache identifiers.
+   *
+   * @return array
+   *   List of cached data keyed by the passed in file paths.
+   */
+  public function getMultiple(array $filepaths) {
+    $file_data = [];
+
+    $filepaths_to_fetch = [];
+
+    // First load from the static cache what we can.
+    foreach ($filepaths as $filepath) {
+      if (!file_exists($filepath)) {
+        continue;
+      }
+
+      $realpath = realpath($filepath);
+      // If the file exists but realpath returns nothing, it is using a stream
+      // wrapper, those are not supported.
+      if (empty($realpath)) {
+        continue;
+      }
+
+      if (isset(static::$cached[$this->context][$realpath]) && static::$cached[$this->context][$realpath]['mtime'] == filemtime($realpath)) {
+        $file_data[$filepath] = static::$cached[$this->context][$realpath]['data'];
+      }
+      else {
+        // Collect a list of filepaths that we need to fetch from apcu.
+        $filepaths_to_fetch[] = static::APC_PREFIX . ':' . $this->context . ':' . $realpath;
+      }
+    }
+
+    // If apcu is available and there are any paths to fetch.
+    if (function_exists('apc_fetch') && $filepaths_to_fetch) {
+      $cache_results = apc_fetch($filepaths_to_fetch) ?: [];
+      foreach ($cache_results as $cache) {
+        if ($cache['mtime'] == filemtime($cache['filepath'])) {
+          $file_data[$cache['filepath']] = $cache['data'];
+          static::$cached[$this->context][$cache['filepath']] = $cache;
+        }
+      }
+    }
+    return $file_data;
+  }
+
+  /**
+   * 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 function set($filepath, $data) {
+    $realpath = realpath($filepath);
+    $cached = [
+      'mtime' => filemtime($filepath),
+      'filepath' => $filepath,
+      'data' => $data,
+    ];
+
+    if (function_exists('apc_store')) {
+      apc_store(static::APC_PREFIX . ':' . $this->context . ':' . $realpath, $cached);
+    }
+    static::$cached[$this->context][$realpath] = $cached;
+  }
+
+  /**
+   * Delete data from the cache.
+   *
+   * @param string $filepath
+   *   Name of the cache that the cached data is based on.
+   */
+  public function delete($filepath) {
+    $realpath = realpath($filepath);
+    if (function_exists('apc_delete')) {
+      apc_delete(static::APC_PREFIX . ':' . $this->context . ':' . $realpath);
+    }
+    unset(static::$cached[$this->context][$realpath]);
+  }
+
+}
diff --git a/core/lib/Drupal/Component/Discovery/YamlDiscovery.php b/core/lib/Drupal/Component/Discovery/YamlDiscovery.php
index bf4ee15..140e1f1 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.
@@ -47,8 +48,25 @@ public function __construct($name, array $directories) {
    */
   public function findAll() {
     $all = array();
-    foreach ($this->findFiles() as $provider => $file) {
-      $all[$provider] = Yaml::decode(file_get_contents($file));
+
+    $files = $this->findFiles();
+    $provider_by_files = array_flip($files);
+
+    $file_cache = new ApcuFileCache('yaml_discovery:' . $this->name);
+
+    // Try to load from the file cache first.
+    foreach ($file_cache->getMultiple($files) as $file => $data) {
+      $all[$provider_by_files[$file]] = $data;
+      unset($provider_by_files[$file]);
+    }
+
+    // If there are files left that were not returned from the cache,
+    // load and parse them now. Note the reversed order.
+    if ($provider_by_files) {
+      foreach ($provider_by_files as $file => $provider) {
+        $all[$provider] = Yaml::decode(file_get_contents($file));
+        $file_cache->set($file, $all[$provider]);
+      }
     }
 
     return $all;
diff --git a/core/lib/Drupal/Core/Config/ExtensionInstallStorage.php b/core/lib/Drupal/Core/Config/ExtensionInstallStorage.php
index cb2833e..12d2d12 100644
--- a/core/lib/Drupal/Core/Config/ExtensionInstallStorage.php
+++ b/core/lib/Drupal/Core/Config/ExtensionInstallStorage.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\Config;
 
+use Drupal\Component\Cache\ApcuFileCache;
 use Drupal\Core\Site\Settings;
 
 /**
@@ -48,9 +49,8 @@ class ExtensionInstallStorage extends InstallStorage {
    *   search.
    */
   public function __construct(StorageInterface $config_storage, $directory = self::CONFIG_INSTALL_DIRECTORY, $collection = StorageInterface::DEFAULT_COLLECTION, $include_profile = TRUE) {
+    parent::__construct($directory, $collection);
     $this->configStorage = $config_storage;
-    $this->directory = $directory;
-    $this->collection = $collection;
     $this->includeProfile = $include_profile;
   }
 
diff --git a/core/lib/Drupal/Core/Config/FileStorage.php b/core/lib/Drupal/Core/Config/FileStorage.php
index f404480..4fec51c 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.
@@ -31,6 +32,13 @@ class FileStorage implements StorageInterface {
   protected $directory = '';
 
   /**
+   * The apcu file cache.
+   *
+   * @var \Drupal\Component\Cache\ApcuFileCache
+   */
+  protected $fileCache;
+
+  /**
    * Constructs a new FileStorage.
    *
    * @param string $directory
@@ -42,6 +50,7 @@ class FileStorage implements StorageInterface {
   public function __construct($directory, $collection = StorageInterface::DEFAULT_COLLECTION) {
     $this->directory = $directory;
     $this->collection = $collection;
+    $this->fileCache = new ApcuFileCache('config');
   }
 
   /**
@@ -93,12 +102,18 @@ public function exists($name) {
    * @throws \Drupal\Core\Config\UnsupportedDataTypeConfigException
    */
   public function read($name) {
+    $filename = $this->getFilePath($name);
+    if ($data = $this->fileCache->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);
+      $this->fileCache->set($filename, $data);
     }
     catch (InvalidDataTypeException $e) {
       throw new UnsupportedDataTypeConfigException(String::format('Invalid data type in config @name: !message', array(
@@ -127,7 +142,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 +152,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 +164,9 @@ public function write($name, array $data) {
     else {
       drupal_chmod($target);
     }
+
+    $this->fileCache->set($target, $data);
+
     return TRUE;
   }
 
@@ -163,6 +181,7 @@ public function delete($name) {
       }
       return FALSE;
     }
+    $this->fileCache->delete($this->getFilePath($name));
     return drupal_unlink($this->getFilePath($name));
   }
 
@@ -174,6 +193,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));
     }
+    $this->fileCache->delete($this->getFilePath($name));
+    $this->fileCache->delete($this->getFilePath($new_name));
     return TRUE;
   }
 
diff --git a/core/lib/Drupal/Core/Config/InstallStorage.php b/core/lib/Drupal/Core/Config/InstallStorage.php
index d4e7d5c..77c5ded 100644
--- a/core/lib/Drupal/Core/Config/InstallStorage.php
+++ b/core/lib/Drupal/Core/Config/InstallStorage.php
@@ -57,8 +57,7 @@ class InstallStorage extends FileStorage {
    *   default collection.
    */
   public function __construct($directory = self::CONFIG_INSTALL_DIRECTORY, $collection = StorageInterface::DEFAULT_COLLECTION) {
-    $this->directory = $directory;
-    $this->collection = $collection;
+    parent::__construct($directory, $collection);
   }
 
   /**
diff --git a/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php b/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php
index d4ae53e..e12efc6 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,30 +35,23 @@ 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;
 
+    /**
+     * Apcu file cache.
+     *
+     * @var \Drupal\Component\Cache\ApcuFileCache
+     */
+    protected $fileCache;
+
+
     public function __construct(ContainerBuilder $container)
     {
       $this->container = $container;
-    }
+      $this->fileCache = new ApcuFileCache('container_yaml_loader');
 
-    /**
-     * Resets the internal cache. This method is mostly useful for tests.
-     */
-    public static function reset()
-    {
-        static::$yaml = array();
     }
 
     /**
@@ -67,10 +61,13 @@ public static function reset()
      */
     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 cache parsed definition objects.
+        $content = $this->fileCache->get($file);
+        if (!$content) {
+          $content = $this->loadFile($file);
+          $this->fileCache->set($file, $content);
         }
-        $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 4681977..46e8438 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;
 
@@ -81,6 +82,13 @@ class ExtensionDiscovery {
   protected $root;
 
   /**
+   * The apcu file cache.
+   *
+   * @var \Drupal\Component\Cache\ApcuFileCache
+   */
+  protected $fileCache;
+
+  /**
    * Constructs a new ExtensionDiscovery object.
    *
    * @param string $root
@@ -88,6 +96,7 @@ class ExtensionDiscovery {
    */
   public function __construct($root) {
     $this->root = $root;
+    $this->fileCache = new ApcuFileCache('extension_discovery');
   }
 
   /**
@@ -406,6 +415,12 @@ protected function scanDirectory($dir, $include_tests) {
       if (!preg_match(static::PHP_FUNCTION_PATTERN, $fileinfo->getBasename('.info.yml'))) {
         continue;
       }
+
+      if ($cached_extension = $this->fileCache->get($fileinfo->getPathName())) {
+        $files[$cached_extension->getType()][$key] = $cached_extension;
+        continue;
+      }
+
       // Determine extension type from info file.
       $type = FALSE;
       $file = $fileinfo->openFile('r');
@@ -441,6 +456,7 @@ protected function scanDirectory($dir, $include_tests) {
       $extension->origin = $dir;
 
       $files[$type][$key] = $extension;
+      $this->fileCache->set($fileinfo->getPathName(), $extension);
     }
     return $files;
   }
diff --git a/core/modules/config/src/Tests/ConfigImportUITest.php b/core/modules/config/src/Tests/ConfigImportUITest.php
index 9bc30e3..71c844e 100644
--- a/core/modules/config/src/Tests/ConfigImportUITest.php
+++ b/core/modules/config/src/Tests/ConfigImportUITest.php
@@ -55,6 +55,10 @@ function testImport() {
 
     // Create updated configuration object.
     $new_site_name = 'Config import test ' . $this->randomString();
+    // Accessing the configuration import UI might have cached the files in the
+    // APC user cache. Wait a second so we can be sure that they get a different
+    // file modification time.
+    sleep(1);
     $this->prepareSiteNameUpdate($new_site_name);
     $this->assertIdentical($staging->exists($name), TRUE, $name . ' found.');
 
diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php
index 7b12fbf..7512598 100644
--- a/core/modules/simpletest/src/WebTestBase.php
+++ b/core/modules/simpletest/src/WebTestBase.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\simpletest;
 
+use Drupal\Component\Cache\ApcuFileCache;
 use Drupal\Component\Serialization\Json;
 use Drupal\Component\Serialization\Yaml;
 use Drupal\Component\Utility\Crypt;
@@ -1046,8 +1047,9 @@ protected function setContainerParameter($name, $value) {
     $services['parameters'][$name] = $value;
     file_put_contents($filename, Yaml::encode($services));
 
-    // Clear the YML file cache.
-    YamlFileLoader::reset();
+    // Ensure that the cache is deleted for the yaml file loader.
+    $file_cache = new ApcuFileCache('container_yaml_loader');
+    $file_cache->delete($filename);
   }
 
   /**
