Convert var_table_t to an unordered_map

Profiling revealed string comparison in variable lookups to be a
significant hotspot. This change causes `make test` to complete ~4.5%
faster per `hyperfine`.
This commit is contained in:
Mahmoud Al-Qudsi 2020-06-25 00:46:32 -05:00
parent a5be15da69
commit c3849ebeba
3 changed files with 11 additions and 4 deletions

View File

@ -635,7 +635,7 @@ std::shared_ptr<const null_terminated_array_t<char>> env_scoped_impl_t::create_e
assert(var && "Variable should be present in uvars");
// Note that std::map::insert does NOT overwrite a value already in the map,
// which we depend on here.
vals.insert(std::make_pair(key, *var));
vals.insert(std::move(std::make_pair(std::move(key), std::move(*var))));
}
}

View File

@ -5,9 +5,9 @@
#include <stddef.h>
#include <stdint.h>
#include <map>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include "common.h"
@ -186,7 +186,7 @@ class env_var_t {
}
bool operator!=(const env_var_t &rhs) const { return !(*this == rhs); }
};
typedef std::map<wcstring, env_var_t> var_table_t;
typedef std::unordered_map<wcstring, env_var_t> var_table_t;
/// An environment is read-only access to variable values.
class environment_t {

View File

@ -441,7 +441,14 @@ std::string env_universal_t::serialize_with_vars(const var_table_t &vars) {
contents.append(SAVE_MSG);
contents.append("# VERSION: " UVARS_VERSION_3_0 "\n");
for (const auto &kv : vars) {
// Preserve legacy behavior by sorting the values first
typedef std::pair<std::reference_wrapper<const wcstring>, std::reference_wrapper<const env_var_t>> env_pair_t;
std::vector<env_pair_t> cloned(vars.begin(), vars.end());
std::sort(cloned.begin(), cloned.end(), [](const env_pair_t &p1, const env_pair_t &p2) {
return p1.first.get() < p2.first.get();
});
for (const auto &kv : cloned) {
// Append the entry. Note that append_file_entry may fail, but that only affects one
// variable; soldier on.
const wcstring &key = kv.first;