From e3f3e8a7a321e16594bd1cd7d5b0661c0f4f54c3 Mon Sep 17 00:00:00 2001 From: Dave Cunningham Date: Tue, 4 Oct 2016 14:01:00 -0400 Subject: [PATCH] Improve performance of repeated same file import --- core/vm.cpp | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/core/vm.cpp b/core/vm.cpp index 020e89075..63feb3a9e 100644 --- a/core/vm.cpp +++ b/core/vm.cpp @@ -460,11 +460,16 @@ class Interpreter { struct ImportCacheValue { std::string foundHere; std::string content; + /** Parsed desugared expression. + * + * Null if this file was only ever successfully imported with importstr. + */ + AST *expr; }; /** Cache for imported Jsonnet files. */ std::map, - const ImportCacheValue *> cachedImports; + ImportCacheValue *> cachedImports; /** External variables for std.extVar. */ ExtMap externalVars; @@ -688,12 +693,16 @@ class Interpreter { */ AST *import(const LocationRange &loc, const LiteralString *file) { - const ImportCacheValue *input = importString(loc, file); - Tokens tokens = jsonnet_lex(input->foundHere, input->content.c_str()); - AST *expr = jsonnet_parse(alloc, tokens); - jsonnet_desugar(alloc, expr, nullptr); - jsonnet_static_analysis(expr); - return expr; + ImportCacheValue *input = importString(loc, file); + if (input->expr == nullptr) { + Tokens tokens = jsonnet_lex(input->foundHere, input->content.c_str()); + AST *expr = jsonnet_parse(alloc, tokens); + jsonnet_desugar(alloc, expr, nullptr); + jsonnet_static_analysis(expr); + // If no errors then populate cache. + input->expr = expr; + } + return input->expr; } /** Import a file as a string. @@ -705,14 +714,14 @@ class Interpreter { * \param file Path to the filename. * \param found_here If non-null, used to store the actual path of the file */ - const ImportCacheValue *importString(const LocationRange &loc, const LiteralString *file) + ImportCacheValue *importString(const LocationRange &loc, const LiteralString *file) { std::string dir = dir_name(loc.file); const String &path = file->value; std::pair key(dir, path); - const ImportCacheValue *cached_value = cachedImports[key]; + ImportCacheValue *cached_value = cachedImports[key]; if (cached_value != nullptr) return cached_value; @@ -734,6 +743,7 @@ class Interpreter { auto *input_ptr = new ImportCacheValue(); input_ptr->foundHere = found_here_cptr; input_ptr->content = input; + input_ptr->expr = nullptr; // May be filled in later by import(). ::free(found_here_cptr); cachedImports[key] = input_ptr; return input_ptr;