diff --git a/core/core.services.yml b/core/core.services.yml
index ba3be7f..696f12c 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -24,6 +24,13 @@ services:
     factory_method: get
     factory_service: cache_factory
     arguments: [config]
+  cache.config_schema:
+    class: Drupal\Core\Cache\CacheBackendInterface
+    tags:
+      - { name: cache.bin }
+    factory_method: get
+    factory_service: cache_factory
+    arguments: [config_schema]
   cache.cache:
     class: Drupal\Core\Cache\CacheBackendInterface
     tags:
@@ -102,6 +109,9 @@ services:
     class: Drupal\Core\Config\DatabaseStorage
     arguments: ['@database', config_snapshot]
   config.storage.schema:
+    class: Drupal\Core\Config\CachedStorage
+    arguments: ['@config.storage.schema.disk', '@cache.config_schema']
+  config.storage.schema.disk:
     class: Drupal\Core\Config\Schema\SchemaStorage
   config.storage.installer:
     class: Drupal\Core\Config\InstallStorage
diff --git a/core/lib/Drupal/Core/Config/Config.php b/core/lib/Drupal/Core/Config/Config.php
index f04bbe0..e73aaec 100644
--- a/core/lib/Drupal/Core/Config/Config.php
+++ b/core/lib/Drupal/Core/Config/Config.php
@@ -11,6 +11,7 @@
 use Drupal\Component\Utility\String;
 use Drupal\Core\Config\ConfigNameException;
 use Drupal\Core\Config\Context\ContextInterface;
+use Drupal\Core\Config\Schema\SchemaIncompleteException;
 use Drupal\Core\TypedData\PrimitiveInterface;
 use Drupal\Core\TypedData\Type\FloatInterface;
 use Drupal\Core\TypedData\Type\IntegerInterface;
@@ -95,6 +96,8 @@ class Config {
    */
   protected $typedConfigManager;
 
+  protected $schemaCache = array();
+
   /**
    * Constructs a configuration object.
    *
@@ -517,37 +520,6 @@ protected function getSchemaWrapper() {
   }
 
   /**
-   * Gets the definition for the configuration key.
-   *
-   * @param string $key
-   *   A string that maps to a key within the configuration data.
-   *
-   * @return \Drupal\Core\Config\Schema\Element
-   *
-   * @throws \Drupal\Core\Config\ConfigException
-   *   Thrown when schema is incomplete.
-   */
-  protected function getSchemaForKey($key) {
-    $parts = explode('.', $key);
-    $schema_wrapper = $this->getSchemaWrapper();
-    if (count($parts) == 1) {
-      $schema = $schema_wrapper->get($key);
-    }
-    else {
-      $schema = clone $schema_wrapper;
-      foreach ($parts as $nested_key) {
-        if (!is_object($schema) || !method_exists($schema, 'get')) {
-          throw new ConfigException(String::format("Incomplete schema for !key key in configuration object !name.", array('!name' => $this->name, '!key' => $key)));
-        }
-        else {
-          $schema = $schema->get($nested_key);
-        }
-      }
-    }
-    return $schema;
-  }
-
-  /**
    * Casts the value to correct data type using the configuration schema.
    *
    * @param string $key
@@ -564,7 +536,7 @@ protected function castValue($key, $value) {
     }
     elseif (is_scalar($value)) {
       try {
-        $element = $this->getSchemaForKey($key);
+        $element = $this->getSchemaWrapper()->get($key);
         if ($element instanceof PrimitiveInterface) {
           // Special handling for integers and floats since the configuration
           // system is primarily concerned with saving values from the Form API
@@ -586,7 +558,7 @@ protected function castValue($key, $value) {
           $value = $element->getString();
         }
       }
-      catch (\Exception $e) {
+      catch (SchemaIncompleteException $e) {
         // @todo throw an exception due to an incomplete schema. Only possible
         //   once https://drupal.org/node/1910624 is complete.
       }
diff --git a/core/lib/Drupal/Core/Config/Schema/Mapping.php b/core/lib/Drupal/Core/Config/Schema/Mapping.php
index 92e9a90..778a585 100644
--- a/core/lib/Drupal/Core/Config/Schema/Mapping.php
+++ b/core/lib/Drupal/Core/Config/Schema/Mapping.php
@@ -11,6 +11,7 @@
 use Drupal\Core\TypedData\ComplexDataInterface;
 use Drupal\Core\TypedData\TypedDataInterface;
 use \InvalidArgumentException;
+use Drupal\Component\Utility\String;
 
 /**
  * Defines a mapping configuration element.
@@ -36,17 +37,29 @@ protected function parse() {
 
   /**
    * Implements Drupal\Core\TypedData\ComplexDataInterface::get().
+   *
+   * Since all configuration objects are mappings the function will except a dot
+   * delimited key to access nested values, for example, 'page.front'.
    */
   public function get($property_name) {
+    $parts = explode('.', $property_name);
+    $root_key = array_shift($parts);
     $elements = $this->getElements();
-    if (isset($elements[$property_name])) {
-      return $elements[$property_name];
+    if (isset($elements[$root_key])) {
+      $element = $elements[$root_key];
     }
     else {
-      throw new InvalidArgumentException(format_string("The configuration property @key doesn't exist.", array(
-          '@key' => $property_name,
-      )));
+      throw new SchemaIncompleteException(String::format("The configuration property @key doesn't exist.", array('@key' => $property_name)));
     }
+
+    // If $property_name contained a dot recurse into the keys.
+    foreach ($parts as $key) {
+     if (!is_object($element) || !method_exists($element, 'get')) {
+        throw new SchemaIncompleteException(String::format("The configuration property @key doesn't exist.", array('!key' => $property_name)));
+      }
+      $element = $element->get($key);
+    }
+    return $element;
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Config/Schema/SchemaIncompleteException.php b/core/lib/Drupal/Core/Config/Schema/SchemaIncompleteException.php
new file mode 100644
index 0000000..9c7c6fc
--- /dev/null
+++ b/core/lib/Drupal/Core/Config/Schema/SchemaIncompleteException.php
@@ -0,0 +1,13 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\Core\Config\Schema\SchemaIncompleteException.
+ */
+
+namespace Drupal\Core\Config\Schema;
+
+/**
+ * An exception thrown when a config schema is incomplete.
+ */
+class SchemaIncompleteException extends \RuntimeException {}
diff --git a/core/lib/Drupal/Core/Config/Schema/Sequence.php b/core/lib/Drupal/Core/Config/Schema/Sequence.php
index 44dbe1d..6333349 100644
--- a/core/lib/Drupal/Core/Config/Schema/Sequence.php
+++ b/core/lib/Drupal/Core/Config/Schema/Sequence.php
@@ -18,7 +18,7 @@ class Sequence extends ArrayElement implements ListInterface {
    * Overrides ArrayElement::parse()
    */
   protected function parse() {
-    $definition = $definition = $this->getItemDefinition();
+    $definition = $this->getItemDefinition();
     $elements = array();
     foreach ($this->value as $key => $value) {
       $elements[$key] = $this->parseElement($key, $value, $definition);
@@ -60,7 +60,7 @@ public function onChange($delta) {
    *   Typed configuration element.
    */
   public function get($key) {
-    $elements = $this->parse();
+    $elements = $this->getElements();
     return $elements[$key];
   }
 
