edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Loader.cs;C444795
File: Loader.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Loader.cs;C444795  (server)    5/21/2008 3:08 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Loader.cs;LoadCache
@@ -38,6 +38,7 @@
         AppendExtensions = 4,
     }
 
+    // TODO: thread safety
     public sealed class Loader {
 
         internal enum FileKind {
@@ -57,8 +58,27 @@
         private readonly RubyArray/*!*/ _loadedFiles;
 
         // files that were required but their execution haven't completed yet:
-        private readonly Stack<string>/*!*/ _unfinishedFiles;
+        private readonly Stack<string>/*!*/ _unfinishedFiles; 
 
+        // TODO: weak hash?
+        // TODO: modification timestamps
+        // maps full normalized path to compiled code:
+        private readonly Dictionary<string, CompiledFile>/*!*/ _compiledFiles;
+
+        private struct CompiledFile {
+            public readonly ScriptCode/*!*/ CompiledCode;
+
+            public CompiledFile(ScriptCode/*!*/ compiledCode) {
+                Assert.NotNull(compiledCode);
+
+                CompiledCode = compiledCode;
+            }
+        }
+
+        // counters:
+        private int _cacheHitCount;
+        private int _compiledFileCount;
+
         /// <summary>
         /// TODO: Thread safety: the user of this object is responsible for locking it.
         /// </summary>
@@ -89,6 +109,7 @@
             _loadPaths = new RubyArray();
             _loadedFiles = new RubyArray();
             _unfinishedFiles = new Stack<string>();
+            _compiledFiles = new Dictionary<string, CompiledFile>(Platform.PathComparer);
         }
 
         /// <summary>
@@ -220,14 +241,10 @@
                 _unfinishedFiles.Push(pathWithExtension.ToString());
 
                 if (file.SourceUnit != null) {
-                    Debug.WriteLine(String.Format("LOAD {0}", file.SourceUnit.Path));
 
                     RubyContext rubySource = file.SourceUnit.LanguageContext as RubyContext;
                     if (rubySource != null) {
-                        RubyCompilerOptions options = new RubyCompilerOptions();
-                        options.IsIncluded = true;
-                        options.IsWrapped = (flags & LoadFlags.LoadIsolated) != 0;
-                        file.SourceUnit.Compile(options, _executionContext.RuntimeErrorSink).Run(context, false);
+                        ExecuteRubySourceUnit(file.SourceUnit, context, flags);
                     } else {
                         // TODO: publish scope?
                         file.SourceUnit.Execute();
@@ -249,6 +266,29 @@
             return true;
         }
 
+        private void ExecuteRubySourceUnit(SourceUnit/*!*/ sourceUnit, CodeContext/*!*/ context, LoadFlags flags) {
+            ScriptCode compiledCode;
+
+            // TODO: check file timestamp
+            string fullPath = Platform.GetFullPath(sourceUnit.Path);
+            CompiledFile compiledFile;
+            if (_compiledFiles.TryGetValue(fullPath, out compiledFile)) {
+                Debug.WriteLine(String.Format("{0}: {1}", ++_cacheHitCount, sourceUnit.Path), "LOAD CACHED");
+
+                compiledCode = compiledFile.CompiledCode;
+            } else {
+                Debug.WriteLine(String.Format("{0}: {1}", ++_compiledFileCount, sourceUnit.Path), "LOAD COMPILED");
+
+                RubyCompilerOptions options = new RubyCompilerOptions();
+                options.IsIncluded = true;
+                options.IsWrapped = (flags & LoadFlags.LoadIsolated) != 0;
+                compiledCode = sourceUnit.Compile(options, _executionContext.RuntimeErrorSink);
+                _compiledFiles[fullPath] = new CompiledFile(compiledCode);
+            }
+
+            compiledCode.Run(context, false);
+        }
+
         private ResolvedFile FindFile(CodeContext/*!*/ context, string/*!*/ path, bool appendExtensions) {
             Assert.NotNull(path);
             bool isAbsolutePath;
===================================================================
