From 428ce65eebccc1992695f075e58b62598f771279 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 2 Aug 2016 09:36:34 +0200 Subject: Optimize out path::normalize() calls --- build2/algorithm.cxx | 3 ++- build2/parser.cxx | 31 ++++++++++++++++++++++++------- build2/search.cxx | 10 ++++++++-- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/build2/algorithm.cxx b/build2/algorithm.cxx index 595603c..fea3d25 100644 --- a/build2/algorithm.cxx +++ b/build2/algorithm.cxx @@ -43,7 +43,8 @@ namespace build2 if (tt == nullptr) fail << "unknown target type " << n.type << " in name " << n; - n.dir.normalize (); + if (!n.dir.empty ()) + n.dir.normalize (); // @@ OUT: for now we assume the prerequisite's out is undetermined. // Would need to pass a pair of names. diff --git a/build2/parser.cxx b/build2/parser.cxx index ce31042..bb724aa 100644 --- a/build2/parser.cxx +++ b/build2/parser.cxx @@ -27,6 +27,8 @@ namespace build2 typedef token_type type; + static const dir_path root_dir ("/"); + class parser::enter_scope { public: @@ -40,14 +42,28 @@ namespace build2 // since "/" is a relative path on Windows (and we use "/" even on // Windows for that gloabl scope). // - if (d != dir_path ("/")) + if (d != root_dir) { - // Relative scopes are opened relative to out, not src. + // Try hard not to call normalize(). Most of the time we will go just + // one level deeper. // + bool n (true); + if (d.relative ()) - d = p.scope_->out_path () / d; + { + // Relative scopes are opened relative to out, not src. + // + if (d.simple () && d.string () != "." && d.string () != "..") + { + d = dir_path (p.scope_->out_path ()) /= d.string (); + n = false; + } + else + d = p.scope_->out_path () / d; + } - d.normalize (); + if (n) + d.normalize (); } p.switch_scope (d); @@ -600,7 +616,8 @@ namespace build2 if (ti == nullptr) fail (ploc) << "unknown target type " << pn.type; - pn.dir.normalize (); + if (!pn.dir.empty ()) + pn.dir.normalize (); // Find or insert. // @@ -800,14 +817,14 @@ namespace build2 // path p (move (n.dir)); if (n.value.empty ()) - p /= path ("buildfile"); + p /= "buildfile"; else { bool d (path::traits::is_separator (n.value.back ())); p /= path (move (n.value)); if (d) - p /= path ("buildfile"); + p /= "buildfile"; } l6 ([&]{trace (l) << "relative path " << p;}); diff --git a/build2/search.cxx b/build2/search.cxx index 6d0a5e9..68191f5 100644 --- a/build2/search.cxx +++ b/build2/search.cxx @@ -107,8 +107,14 @@ namespace build2 // Check if there is a file. // const dir_path& s (pk.scope->src_path ()); - path f (s / *tk.dir / path (*tk.name)); - f.normalize (); + + path f (s); + if (!tk.dir->empty ()) + { + f /= *tk.dir; + f.normalize (); + } + f /= *tk.name; if (!ext->empty ()) { -- cgit v1.1