perf: use string view everywhere

This has the potential to avoid allocations when something non allocated
is implicitly converted.
This commit is contained in:
Steffen Winter
2025-05-01 17:42:51 +02:00
committed by Jakob P. Liljenberg
parent c52b2c4c93
commit 2538d89ed9
10 changed files with 95 additions and 69 deletions

View File

@@ -16,12 +16,13 @@ indent = tab
tab-size = 4
*/
#include <array>
#include <algorithm>
#include <array>
#include <cmath>
#include <ranges>
#include <stdexcept>
#include <string>
#include <string_view>
#include <utility>
#include "btop_draw.hpp"
@@ -31,6 +32,7 @@ tab-size = 4
#include "btop_tools.hpp"
#include "btop_input.hpp"
#include "btop_menu.hpp"
#include <fmt/format.h>
using std::array;
@@ -151,7 +153,7 @@ namespace Draw {
upos = ulen(this->text);
}
bool TextEdit::command(const string& key) {
bool TextEdit::command(const std::string_view key) {
if (key == "left" and upos > 0) {
upos--;
pos = uresize(text, upos).size();
@@ -193,7 +195,7 @@ namespace Draw {
upos++;
}
else {
const string first = uresize(text, upos) + key;
const auto first = fmt::format("{}{}", uresize(text, upos), key);
text = first + text.substr(pos);
upos++;
pos = first.size();
@@ -245,9 +247,10 @@ namespace Draw {
this->text.clear();
}
string createBox(const int x, const int y, const int width,
const int height, string line_color, bool fill,
const string title, const string title2, const int num) {
string createBox(
const int x, const int y, const int width, const int height, string line_color, bool fill, const std::string_view title,
const std::string_view title2, const int num
) {
string out;
if (line_color.empty())
@@ -283,12 +286,16 @@ namespace Draw {
//? Draw titles if defined
if (not title.empty()) {
out += Mv::to(y, x + 2) + Symbols::title_left + Fx::b + numbering + Theme::c("title") + title
+ Fx::ub + line_color + Symbols::title_right;
out += fmt::format(
"{}{}{}{}{}{}{}{}{}", Mv::to(y, x + 2), Symbols::title_left, Fx::b, numbering, Theme::c("title"), title, Fx::ub,
line_color, Symbols::title_right
);
}
if (not title2.empty()) {
out += Mv::to(y + height - 1, x + 2) + Symbols::title_left_down + Fx::b + numbering + Theme::c("title") + title2
+ Fx::ub + line_color + Symbols::title_right_down;
out += fmt::format(
"{}{}{}{}{}{}{}{}{}", Mv::to(y, x + 2), Symbols::title_left, Fx::b, numbering, Theme::c("title"), title2, Fx::ub,
line_color, Symbols::title_right_down
);
}
return out + Fx::reset + Mv::to(y + 1, x + 1);
@@ -1482,7 +1489,7 @@ namespace Proc {
string box;
int selection(const string& cmd_key) {
int selection(const std::string_view cmd_key) {
auto start = Config::getI("proc_start");
auto selected = Config::getI("proc_selected");
auto last_selected = Config::getI("proc_last_selected");
@@ -1526,7 +1533,7 @@ namespace Proc {
if (selected > 0) selected = select_max;
}
else if (cmd_key.starts_with("mousey")) {
int mouse_y = std::stoi(cmd_key.substr(6));
int mouse_y = std::atoi(cmd_key.substr(6).data());
start = clamp((int)round((double)mouse_y * (numpids - select_max - 2) / (select_max - 2)), 0, max(0, numpids - select_max));
}

View File

@@ -18,11 +18,12 @@ tab-size = 4
#pragma once
#include <string>
#include <vector>
#include <array>
#include <unordered_map>
#include <deque>
#include <string>
#include <string_view>
#include <unordered_map>
#include <vector>
using std::array;
using std::deque;
@@ -72,15 +73,16 @@ namespace Draw {
string text;
TextEdit();
explicit TextEdit(string text, bool numeric=false);
bool command(const string& key);
bool command(const std::string_view key);
string operator()(const size_t limit=0);
void clear();
};
//* Create a box and return as a string
string createBox(const int x, const int y, const int width,
const int height, string line_color = "", bool fill = false,
const string title = "", const string title2 = "", const int num = 0);
string createBox(
const int x, const int y, const int width, const int height, string line_color = "", bool fill = false,
const std::string_view title = "", const std::string_view title2 = "", const int num = 0
);
bool update_clock(bool force = false);

View File

@@ -21,6 +21,7 @@ tab-size = 4
#include <vector>
#include <thread>
#include <mutex>
#include <fmt/format.h>
#include <signal.h>
#include <sys/select.h>
#include <utility>
@@ -203,7 +204,7 @@ namespace Input {
// do not need it, actually
}
void process(const string& key) {
void process(const std::string_view key) {
if (key.empty()) return;
try {
auto filtering = Config::getB("proc_filtering");
@@ -213,7 +214,7 @@ namespace Input {
//? Global input actions
if (not filtering) {
bool keep_going = false;
if (str_to_lower(key) == "q") {
if (key == "q") {
clean_quit(0);
}
else if (is_in(key, "escape", "m")) {
@@ -229,7 +230,7 @@ namespace Input {
return;
}
else if (key.size() == 1 and isint(key)) {
auto intKey = stoi(key);
auto intKey = std::atoi(key.data());
#ifdef GPU_SUPPORT
static const array<string, 10> boxes = {"gpu5", "cpu", "mem", "net", "proc", "gpu0", "gpu1", "gpu2", "gpu3", "gpu4"};
if ((intKey == 0 and Gpu::count < 5) or (intKey >= 5 and intKey - 4 > Gpu::count))
@@ -540,8 +541,7 @@ namespace Input {
}
catch (const std::exception& e) {
throw std::runtime_error("Input::process(\"" + key + "\") : " + string{e.what()});
throw std::runtime_error { fmt::format(R"(Input::process("{}"))", e.what()) };
}
}
}

View File

@@ -18,11 +18,12 @@ tab-size = 4
#pragma once
#include <string>
#include <atomic>
#include <array>
#include <unordered_map>
#include <atomic>
#include <deque>
#include <string>
#include <string_view>
#include <unordered_map>
using std::array;
using std::atomic;
@@ -72,6 +73,6 @@ namespace Input {
void clear();
//* Process actions for input <key>
void process(const string& key);
void process(const std::string_view key);
}

View File

@@ -16,20 +16,22 @@ indent = tab
tab-size = 4
*/
#include <deque>
#include <unordered_map>
#include <array>
#include <signal.h>
#include <errno.h>
#include <cmath>
#include <filesystem>
#include "btop_menu.hpp"
#include "btop_tools.hpp"
#include "btop_config.hpp"
#include "btop_theme.hpp"
#include "btop_draw.hpp"
#include "btop_shared.hpp"
#include "btop_theme.hpp"
#include "btop_tools.hpp"
#include <errno.h>
#include <signal.h>
#include <array>
#include <cmath>
#include <filesystem>
#include <unordered_map>
#include <utility>
using std::array;
using std::ceil;
@@ -798,7 +800,7 @@ namespace Menu {
};
msgBox::msgBox() {}
msgBox::msgBox(int width, int boxtype, const vector<string>& content, string title)
msgBox::msgBox(int width, int boxtype, const vector<string>& content, const std::string_view title)
: width(width), boxtype(boxtype) {
auto tty_mode = Config::getB("tty_mode");
auto rounded = Config::getB("rounded_corners");
@@ -1597,7 +1599,7 @@ static int optionsMenu(const string& key) {
};
bitset<8> menuMask;
void process(string key) {
void process(const std::string_view key) {
if (menuMask.none()) {
Menu::active = false;
Global::overlay.clear();
@@ -1627,7 +1629,7 @@ static int optionsMenu(const string& key) {
}
auto retCode = menuFunc.at(currentMenu)(key);
auto retCode = menuFunc.at(currentMenu)(key.data());
if (retCode == Closed) {
menuMask.reset(currentMenu);
mouse_mappings.clear();

View File

@@ -18,10 +18,11 @@ tab-size = 4
#pragma once
#include <string>
#include <atomic>
#include <vector>
#include <bitset>
#include <string>
#include <string_view>
#include <vector>
#include "btop_input.hpp"
@@ -61,7 +62,7 @@ namespace Menu {
Select
};
msgBox();
msgBox(int width, int boxtype, const vector<string>& content, string title);
msgBox(int width, int boxtype, const vector<string>& content, std::string_view title);
//? Draw and return box as a string
string operator()();
@@ -87,7 +88,7 @@ namespace Menu {
};
//* Handles redirection of input for menu functions and handles return codes
void process(string key="");
void process(const std::string_view key = "");
//* Show a menu from enum Menu::Menus
void show(int menu, int signal=-1);

View File

@@ -23,9 +23,11 @@ tab-size = 4
#include <deque>
#include <filesystem>
#include <string>
#include <string_view>
#include <tuple>
#include <vector>
#include <unordered_map>
#include <vector>
#include <unistd.h>
// From `man 3 getifaddrs`: <net/if.h> must be included before <ifaddrs.h>
@@ -67,7 +69,6 @@ namespace Global {
}
namespace Runner {
extern atomic<bool> active;
extern atomic<bool> reading;
extern atomic<bool> stopping;
@@ -414,7 +415,7 @@ namespace Proc {
auto collect(bool no_update = false) -> vector<proc_info>&;
//* Update current selection and view, returns -1 if no change otherwise the current selection
int selection(const string& cmd_key);
int selection(const std::string_view cmd_key);
//* Draw contents of proc box using <plist> as data source
string draw(const vector<proc_info>& plist, bool force_redraw = false, bool data_same = false);

View File

@@ -26,6 +26,7 @@ tab-size = 4
#include <optional>
#include <ranges>
#include <sstream>
#include <string_view>
#include <utility>
#include <fcntl.h>
@@ -33,7 +34,6 @@ tab-size = 4
#include <termios.h>
#include <unistd.h>
#include "unordered_map"
#include "widechar_width.hpp"
#include "btop_shared.hpp"
#include "btop_tools.hpp"
@@ -211,11 +211,11 @@ namespace Term {
namespace Tools {
size_t wide_ulen(const string& str) {
size_t wide_ulen(const std::string_view str) {
unsigned int chars = 0;
try {
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
auto w_str = conv.from_bytes((str.size() > 10000 ? str.substr(0, 10000).c_str() : str.c_str()));
auto w_str = conv.from_bytes((str.size() > 10000 ? str.substr(0, 10000).data() : str.data()));
for (auto c : w_str) {
chars += utf8::wcwidth(c);
@@ -228,7 +228,7 @@ namespace Tools {
return chars;
}
size_t wide_ulen(const std::wstring& w_str) {
size_t wide_ulen(const std::wstring_view w_str) {
unsigned int chars = 0;
for (auto c : w_str) {
@@ -682,7 +682,7 @@ namespace Logger {
loglevel = v_index(log_levels, level);
}
void log_write(const Level level, const string& msg) {
void log_write(const Level level, const std::string_view msg) {
if (loglevel < level or !logfile.has_value()) {
return;
}

View File

@@ -28,16 +28,16 @@ tab-size = 4
#include <chrono>
#include <cstdint>
#include <filesystem>
#include <limits.h>
#include <pthread.h>
#include <ranges>
#include <regex>
#include <string>
#include <string_view>
#include <thread>
#include <tuple>
#include <vector>
#include <pthread.h>
#include <limits.h>
#include <unordered_map>
#include <vector>
#ifdef BTOP_DEBUG
#include <source_location>
#endif
@@ -177,11 +177,23 @@ namespace Logger {
//* Set log level, valid arguments: "DISABLED", "ERROR", "WARNING", "INFO" and "DEBUG"
void set(const string& level);
void log_write(const Level level, const string& msg);
inline void error(const string msg) { log_write(ERROR, msg); }
inline void warning(const string msg) { log_write(WARNING, msg); }
inline void info(const string msg) { log_write(INFO, msg); }
inline void debug(const string msg) { log_write(DEBUG, msg); }
void log_write(const Level level, const std::string_view msg);
inline void error(const std::string_view msg) {
log_write(ERROR, msg);
}
inline void warning(const std::string_view msg) {
log_write(WARNING, msg);
}
inline void info(const std::string_view msg) {
log_write(INFO, msg);
}
inline void debug(const std::string_view msg) {
log_write(DEBUG, msg);
}
}
//? --------------------------------------------------- FUNCTIONS -----------------------------------------------------
@@ -195,11 +207,11 @@ namespace Tools {
virtual std::string do_grouping() const override { return "\03"; }
};
size_t wide_ulen(const string& str);
size_t wide_ulen(const std::wstring& w_str);
size_t wide_ulen(const std::string_view str);
size_t wide_ulen(const std::wstring_view w_str);
//* Return number of UTF8 characters in a string (wide=true for column size needed on terminal)
inline size_t ulen(const string& str, bool wide = false) {
inline size_t ulen(const std::string_view str, bool wide = false) {
return (wide ? wide_ulen(str) : std::ranges::count_if(str, [](char c) { return (static_cast<unsigned char>(c) & 0xC0) != 0x80; }));
}
@@ -238,12 +250,12 @@ namespace Tools {
//* Check if string <str> contains value <find_val>
template <typename T>
inline bool s_contains(const string& str, const T& find_val) {
constexpr bool s_contains(const std::string_view str, const T& find_val) {
return str.find(find_val) != string::npos;
}
//* Check if string <str> contains string <find_val>, while ignoring case
inline bool s_contains_ic(const string& str, const string& find_val) {
inline bool s_contains_ic(const std::string_view str, const std::string_view find_val) {
auto it = std::search(
str.begin(), str.end(),
find_val.begin(), find_val.end(),
@@ -280,12 +292,12 @@ namespace Tools {
}
//* Check if a string is a valid bool value
inline bool isbool(const string& str) {
inline bool isbool(const std::string_view str) {
return is_in(str, "true", "false", "True", "False");
}
//* Convert string to bool, returning any value not equal to "true" or "True" as false
inline bool stobool(const string& str) {
inline bool stobool(const std::string_view str) {
return is_in(str, "true", "True");
}

View File

@@ -388,7 +388,7 @@ namespace Cpu {
fs::path add_path = fs::canonical(dir.path());
if (v_contains(search_paths, add_path) or v_contains(search_paths, add_path / "device")) continue;
if (s_contains(add_path, "coretemp"))
if (s_contains(add_path.c_str(), "coretemp"))
got_coretemp = true;
for (const auto & file : fs::directory_iterator(add_path)) {