Miscellaneous optimizations to reduce string copying

This commit is contained in:
ridiculousfish 2014-01-07 14:57:58 -08:00
parent cb6be2a50d
commit b34721b3f4
7 changed files with 50 additions and 35 deletions

View File

@ -4460,7 +4460,7 @@ void builtin_get_names(std::vector<completion_t> &list)
{
for (size_t i=0; i < BUILTIN_COUNT; i++)
{
list.push_back(completion_t(builtin_datas[i].name));
append_completion(list, builtin_datas[i].name);
}
}

View File

@ -466,7 +466,13 @@ void completion_autoload_t::command_removed(const wcstring &cmd)
/** Create a new completion entry */
void append_completion(std::vector<completion_t> &completions, const wcstring &comp, const wcstring &desc, complete_flags_t flags, string_fuzzy_match_t match)
{
completions.push_back(completion_t(comp, desc, match, flags));
/* If we just constructed the completion and used push_back, we would get two string copies. Try to avoid that by making a stubby completion in the vector first, and then copying our string in. */
completions.push_back(completion_t(wcstring()));
completion_t *last = &completions.back();
last->completion = comp;
last->description = desc;
last->match = match;
last->flags = flags;
}
/**
@ -1191,7 +1197,7 @@ void completer_t::complete_cmd(const wcstring &str_cmd, bool use_function, bool
wcstring_list_t names = function_get_names(str_cmd.at(0) == L'_');
for (size_t i=0; i < names.size(); i++)
{
possible_comp.push_back(completion_t(names.at(i)));
append_completion(possible_comp, names.at(i));
}
this->complete_strings(str_cmd, 0, &complete_function_desc, possible_comp, 0);

View File

@ -124,7 +124,7 @@ public:
int flags;
/* Construction. Note: defining these so that they are not inlined reduces the executable size. */
completion_t(const wcstring &comp, const wcstring &desc = L"", string_fuzzy_match_t match = string_fuzzy_match_t(fuzzy_match_exact), int flags_val = 0);
completion_t(const wcstring &comp, const wcstring &desc = wcstring(), string_fuzzy_match_t match = string_fuzzy_match_t(fuzzy_match_exact), int flags_val = 0);
completion_t(const completion_t &);
completion_t &operator=(const completion_t &);
@ -268,7 +268,7 @@ void complete_load(const wcstring &cmd, bool reload);
\param flags completion flags
*/
void append_completion(std::vector<completion_t> &completions, const wcstring &comp, const wcstring &desc = L"", int flags = 0, string_fuzzy_match_t match = string_fuzzy_match_t(fuzzy_match_exact));
void append_completion(std::vector<completion_t> &completions, const wcstring &comp, const wcstring &desc = wcstring(), int flags = 0, string_fuzzy_match_t match = string_fuzzy_match_t(fuzzy_match_exact));
/* Function used for testing */
void complete_set_variable_names(const wcstring_list_t *names);

View File

@ -892,6 +892,7 @@ int env_set(const wcstring &key, const wchar_t *val, int var_mode)
if (!is_universal)
{
event_t ev = event_t::variable_event(key);
ev.arguments.reserve(3);
ev.arguments.push_back(L"VARIABLE");
ev.arguments.push_back(L"SET");
ev.arguments.push_back(key);

View File

@ -785,7 +785,15 @@ static int expand_pid(const wcstring &instr_with_sep,
expand_flags_t flags,
std::vector<completion_t> &out)
{
/* Hack. If there's no INTERNAL_SEP and no PROCESS_EXPAND, then there's nothing to do. Check out this "null terminated string." */
const wchar_t some_chars[] = {INTERNAL_SEPARATOR, PROCESS_EXPAND, L'\0'};
if (instr_with_sep.find_first_of(some_chars) == wcstring::npos)
{
/* Nothing to do */
append_completion(out, instr_with_sep);
return 1;
}
/* expand_string calls us with internal separators in instr...sigh */
wcstring instr = instr_with_sep;
remove_internal_separator(instr, false);
@ -1372,7 +1380,7 @@ static int expand_brackets(parser_t &parser, const wcstring &instr, int flags, s
/**
Perform cmdsubst expansion
*/
static int expand_cmdsubst(parser_t &parser, const wcstring &input, std::vector<completion_t> &outList)
static int expand_cmdsubst(parser_t &parser, const wcstring &input, std::vector<completion_t> &out_list)
{
wchar_t *paran_begin=0, *paran_end=0;
std::vector<wcstring> sub_res;
@ -1390,7 +1398,7 @@ static int expand_cmdsubst(parser_t &parser, const wcstring &input, std::vector<
L"Mismatched parenthesis");
return 0;
case 0:
outList.push_back(completion_t(input));
append_completion(out_list, input);
return 1;
case 1:
@ -1455,15 +1463,15 @@ static int expand_cmdsubst(parser_t &parser, const wcstring &input, std::vector<
*/
for (i=0; i<sub_res.size(); i++)
{
wcstring sub_item = sub_res.at(i);
wcstring sub_item2 = escape_string(sub_item, 1);
const wcstring &sub_item = sub_res.at(i);
const wcstring sub_item2 = escape_string(sub_item, 1);
wcstring whole_item;
for (j=0; j < tail_expand.size(); j++)
{
wcstring whole_item;
wcstring tail_item = tail_expand.at(j).completion;
whole_item.clear();
const wcstring &tail_item = tail_expand.at(j).completion;
//sb_append_substring( &whole_item, in, len1 );
whole_item.append(in, paran_begin-in);
@ -1481,7 +1489,7 @@ static int expand_cmdsubst(parser_t &parser, const wcstring &input, std::vector<
whole_item.append(tail_item);
//al_push( out, whole_item.buff );
outList.push_back(completion_t(whole_item));
append_completion(out_list, whole_item);
}
}
@ -1665,7 +1673,7 @@ int expand_string(const wcstring &input, std::vector<completion_t> &output, expa
if ((!(flags & ACCEPT_INCOMPLETE)) && expand_is_clean(input.c_str()))
{
output.push_back(completion_t(input));
append_completion(output, input);
return EXPAND_OK;
}
@ -1681,7 +1689,7 @@ int expand_string(const wcstring &input, std::vector<completion_t> &output, expa
parser.error(CMDSUBST_ERROR, -1, L"Command substitutions not allowed");
return EXPAND_ERROR;
}
in->push_back(completion_t(input));
append_completion(*in, input);
}
else
{
@ -1709,7 +1717,7 @@ int expand_string(const wcstring &input, std::vector<completion_t> &output, expa
next[i] = L'$';
}
}
out->push_back(completion_t(next));
append_completion(*out, next);
}
else
{
@ -1725,7 +1733,7 @@ int expand_string(const wcstring &input, std::vector<completion_t> &output, expa
for (i=0; i < in->size(); i++)
{
wcstring next = in->at(i).completion;
const wcstring &next = in->at(i).completion;
if (!expand_brackets(parser, next, flags, *out))
{
@ -1745,7 +1753,7 @@ int expand_string(const wcstring &input, std::vector<completion_t> &output, expa
if (flags & ACCEPT_INCOMPLETE)
{
if (next[0] == PROCESS_EXPAND)
if (! next.empty() && next.at(0) == PROCESS_EXPAND)
{
/*
If process expansion matches, we are not
@ -1758,7 +1766,7 @@ int expand_string(const wcstring &input, std::vector<completion_t> &output, expa
}
else
{
out->push_back(completion_t(next));
append_completion(*out, next);
}
}
else
@ -1840,7 +1848,7 @@ int expand_string(const wcstring &input, std::vector<completion_t> &output, expa
{
if (!(flags & ACCEPT_INCOMPLETE))
{
out->push_back(completion_t(next_str));
append_completion(*out, next_str);
}
}
}
@ -1970,19 +1978,19 @@ bool fish_openSUSE_dbus_hack_hack_hack_hack(std::vector<completion_t> *args)
val.resize(last_good + 1);
args->clear();
args->push_back(completion_t(L"set"));
append_completion(*args, L"set");
if (key == L"DBUS_SESSION_BUS_ADDRESS")
args->push_back(completion_t(L"-x"));
args->push_back(completion_t(key));
args->push_back(completion_t(val));
append_completion(*args, L"-x");
append_completion(*args, key);
append_completion(*args, val);
result = true;
}
else if (string_prefixes_string(L"export DBUS_SESSION_BUS_ADDRESS;", cmd))
{
/* Nothing, we already exported it */
args->clear();
args->push_back(completion_t(L"echo"));
args->push_back(completion_t(L"-n"));
append_completion(*args, L"echo");
append_completion(*args, L"-n");
result = true;
}
}

View File

@ -805,11 +805,11 @@ parse_execution_result_t parse_execution_context_t::populate_plain_process(job_t
return parse_execution_errored;
}
wcstring actual_cmd;
wcstring path_to_external_command;
if (process_type == EXTERNAL)
{
/* Determine the actual command. This may be an implicit cd. */
bool has_command = path_get_path(cmd, &actual_cmd);
bool has_command = path_get_path(cmd, &path_to_external_command);
/* If there was no command, then we care about the value of errno after checking for it, to distinguish between e.g. no file vs permissions problem */
const int no_cmd_err_code = errno;
@ -843,7 +843,7 @@ parse_execution_result_t parse_execution_context_t::populate_plain_process(job_t
/* Implicit cd is simple */
argument_list.push_back(L"cd");
argument_list.push_back(cmd);
actual_cmd.clear();
path_to_external_command.clear();
/* If we have defined a wrapper around cd, use it, otherwise use the cd builtin */
process_type = function_exists(L"cd") ? INTERNAL_FUNCTION : INTERNAL_BUILTIN;
@ -878,7 +878,7 @@ parse_execution_result_t parse_execution_context_t::populate_plain_process(job_t
proc->type = process_type;
proc->set_argv(argument_list);
proc->set_io_chain(process_io_chain);
proc->actual_cmd = actual_cmd;
proc->actual_cmd = path_to_external_command;
return parse_execution_success;
}

View File

@ -1939,7 +1939,7 @@ int parser_t::parse_job(process_t *p, job_t *j, tokenizer_t *tok)
}
}
}
args.push_back(completion_t(nxt));
append_completion(args, nxt);
}
if (error_code == 0)
@ -1982,8 +1982,8 @@ int parser_t::parse_job(process_t *p, job_t *j, tokenizer_t *tok)
if (use_implicit_cd)
{
args.clear();
args.push_back(completion_t(L"cd"));
args.push_back(completion_t(implicit_cd_path));
append_completion(args, L"cd");
append_completion(args, implicit_cd_path);
/* If we have defined a wrapper around cd, use it, otherwise use the cd builtin */
if (use_function && function_exists(L"cd"))