diff --git a/core/includes/config.inc b/core/includes/config.inc
index 00c7fa6..9690af8 100644
--- a/core/includes/config.inc
+++ b/core/includes/config.inc
@@ -102,7 +102,7 @@ function config_get_storage_names_with_prefix($prefix = '') {
  *   A configuration object.
  */
 function config($name) {
-  return drupal_container()->get('config.factory')->get($name)->load();
+  return drupal_container()->get('config.factory')->get($name);
 }
 
 /**
diff --git a/core/lib/Drupal/Core/Config/Config.php b/core/lib/Drupal/Core/Config/Config.php
index 6fc2a87..5c299f1 100644
--- a/core/lib/Drupal/Core/Config/Config.php
+++ b/core/lib/Drupal/Core/Config/Config.php
@@ -65,6 +65,13 @@ class Config {
   protected $eventDispatcher;
 
   /**
+   * Whether the config object has already been loaded.
+   *
+   * @var bool
+   */
+  protected $isLoaded = FALSE;
+
+  /**
    * Constructs a configuration object.
    *
    * @param string $name
@@ -151,6 +158,9 @@ public function isNew() {
    *   The data that was requested.
    */
   public function get($key = '') {
+    if (!$this->isLoaded) {
+      $this->load();
+    }
     if (!isset($this->overriddenData)) {
       $this->setOverriddenData();
     }
@@ -180,6 +190,8 @@ public function get($key = '') {
    */
   public function setData(array $data) {
     $this->data = $data;
+    // When importing new config, a load would destroy the data just set.
+    $this->isLoaded = TRUE;
     $this->resetOverriddenData();
     return $this;
   }
@@ -243,6 +255,9 @@ protected function resetOverriddenData() {
    *   The configuration object.
    */
   public function set($key, $value) {
+    if (!$this->isLoaded) {
+      $this->load();
+    }
     // Type-cast value into a string.
     $value = $this->castValue($value);
 
@@ -309,6 +324,9 @@ public function castValue($value) {
    *   The configuration object.
    */
   public function clear($key) {
+    if (!$this->isLoaded) {
+      $this->load();
+    }
     $parts = explode('.', $key);
     if (count($parts) == 1) {
       unset($this->data[$key]);
@@ -337,6 +355,7 @@ public function load() {
       $this->setData($data);
     }
     $this->notify('load');
+    $this->isLoaded = TRUE;
     return $this;
   }
 
@@ -347,6 +366,9 @@ public function load() {
    *   The configuration object.
    */
   public function save() {
+    if (!$this->isLoaded) {
+      $this->load();
+    }
     $this->storage->write($this->name, $this->data);
     $this->isNew = FALSE;
     $this->notify('save');
@@ -412,6 +434,9 @@ protected function notify($config_event_name) {
    *   The configuration object.
    */
   public function merge(array $data_to_merge) {
+    if (!$this->isLoaded) {
+      $this->load();
+    }
     // Preserve integer keys so that config keys are not changed.
     $this->data = NestedArray::mergeDeepArray(array($this->data, $data_to_merge), TRUE);
     return $this;
diff --git a/core/lib/Drupal/Core/Config/ConfigFactory.php b/core/lib/Drupal/Core/Config/ConfigFactory.php
index ca36ce7..9137ce2 100644
--- a/core/lib/Drupal/Core/Config/ConfigFactory.php
+++ b/core/lib/Drupal/Core/Config/ConfigFactory.php
@@ -38,6 +38,8 @@ class ConfigFactory {
    */
   protected $eventDispatcher;
 
+  protected $configs = array();
+
   /**
    * Constructs the Config factory.
    *
@@ -64,26 +66,15 @@ public function __construct(StorageInterface $storage, EventDispatcher $event_di
   public function get($name) {
     global $conf;
 
-    // @todo Caching the instantiated objects per name might cut off a fair
-    //   amount of CPU time and memory. Only the data within the configuration
-    //   object changes, so the additional cost of instantiating duplicate
-    //   objects could possibly be avoided. It is not uncommon for a
-    //   configuration object to be retrieved many times during a single
-    //   request; e.g., 'system.performance' alone is retrieved around 10-20
-    //   times within a single page request. Sub-requests via HttpKernel will
-    //   most likely only increase these counts.
-    // @todo Benchmarks were performed with a script that essentially retained
-    //   all instantiated configuration objects in memory until script execution
-    //   ended. A variant of that script called config() within a helper
-    //   function only, which inherently meant that PHP destroyed all
-    //   configuration objects after leaving the function. Consequently,
-    //   benchmark results looked entirely different. Profiling should probably
-    //   redone under more realistic conditions; e.g., actual HTTP requests.
+    if (isset($this->configs[$name])) {
+      return $this->configs[$name];
+    }
+
     // @todo The decrease of CPU time is interesting, since that means that
     //   ContainerBuilder involves plenty of function calls (which are known to
     //   be slow in PHP).
-    $config = new Config($name, $this->storage, $this->eventDispatcher);
-    return $config->init();
+    $this->configs[$name] = new Config($name, $this->storage, $this->eventDispatcher);
+    return $this->configs[$name]->init();
   }
 
 }
