- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在设计我的库时,我构造了很多对象,想知道这是否会导致它效率低下。
我创建了一个库来创建和运行查询。查询是一个类,它采用对 Bind
对象的 initializer_list
的右值引用。每个 Bind
都有一些值。
我认为这种设计效率低下,因为如果我们使用 const char*
,每个 Bind
对象都将复制其值(字符串除外) .最重要的是,我们必须为每个值构建一个完整的 Bind
对象。然后我将所有 Bind
舍入到一个 initializer_list
并将它们移动到一个 vector
中,我不确定有多少开销.这是在 Query
对象中创建的,构建起来可能不会那么昂贵,并且只创建了一个 Query
对象。
查看代码片段底部的 main
函数可能就是您需要查看的全部内容。
class Database {
public:
Database() = default;
~Database() = default;
Result run(Query&& query);
};
class Query {
public:
Query(const char* query, std::initializer_list<Bind>&& binds);
~Query() = default;
...
private:
std::string m_query;
std::vector<Bind> m_binds;
};
Query::Query(const char* query, std::initializer_list<Bind>&& binds) : m_query(query), m_binds(binds) {}
class Bind {
friend Query;
public:
explicit Bind(int32_t i);
explicit Bind(int64_t i);
explicit Bind(uint32_t i);
explicit Bind(float f);
explicit Bind(const char* str);
private:
int bind(sqlite3_stmt* stmt, int column);
ColumnType m_type;
union {
int64_t m_i;
float m_f;
const char* m_str;
};
size_t m_str_size;
};
int main()
{
Database db;
auto result = db.run(Query(
"INSERT INTO users VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
Bind(id),
Bind(first_name),
Bind(last_name),
Bind(age),
Bind(height),
Bind(weight),
Bind(siblings),
Bind(hometown),
Bind(mom),
Bind(dad),
Bind(num_pets),
Bind(os::time_since_epoch()),
Bind(location),
Bind(json),
}));
return 0;
}
最佳答案
内部std::initializer_list<T>
只是几个指针。这些没什么好搬的。所以通过 &&
没有多大意义。标准库按值获取它,我建议你也这样做。 Bind
里面没什么可搬的要么。
如果全部Bind
构造函数只有一个参数,您可以制作一个可变参数构造函数并构造每个 Bind
就地 emplace_back()
:
class Query {
public:
template<class... Bind_args>
Query(const char* query, Bind_args&&... bind_args) {
m_binds.reserve(sizeof...(Bind_args));
(m_binds.emplace_back(std::forward<Bind_args>(bind_args)), ...);
}
private:
std::vector<Bind> m_binds;
};
这将简化 Query
build
query("INSERT INTO users VALUES (?, ?, ?)", 1, "33", 2.f);
如果不进行概要分析,很难说它是否会更有效率。如今,编译器(和链接器)可以非常擅长代码优化,您描述的所有这些开销都可能被完全优化掉。
如果带有折叠表达式的 C++17 不可用,您可以将折叠表达式替换为 C++11 版本:
int sink[] = {(m_binds.emplace_back(std::forward<Bind_args>(bind_args)), 0)...};
(void)sink;
The
Bind
interface needs to support multiple arguments
然后这些参数可以打包成元组:
class Query {
public:
template<class... Tuples>
Query(const char* query, Tuples&&... bind_arg_tuples) {
m_binds.reserve(sizeof...(Tuples));
(emplace_from_tuple(std::forward<Tuples>(bind_arg_tuples)), ...);
}
private:
template<class Tuple>
void emplace_from_tuple(Tuple&& arg_tuple) {
emplace_from_tuple(std::forward<Tuple>(arg_tuple),
std::make_index_sequence<std::tuple_size_v<std::decay_t<Tuple>>>{});
}
template<class Tuple, std::size_t... is>
void emplace_from_tuple(Tuple&& arg_tuple, std::index_sequence<is...>) {
m_binds.emplace_back(std::get<is>(std::forward<Tuple>(arg_tuple))...);
}
private:
std::vector<Bind> m_binds;
};
query("INSERT INTO users VALUES (?, ?, ?)",
std::tuple(1, 2), std::tuple("33", "44"), std::tuple(2.f, 3.f));
此代码避免调用 Bind
的复制构造函数并正确移动所有参数(包括只能移动的类型,如 std::unique_ptr
)。但对于轻量化Bind
反对这可能是一个不必要的过度复杂化。
关于c++ - 我创建了一个库,想知道设计是否效率低下,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58987788/
使用登录后,我想吐出用户名。 但是,当我尝试单击登录按钮时, 它给了我力量。 我看着logcat,但是什么也没显示。 这种编码是在说。 它将根据我在登录屏幕中输入的名称来烘烤用户名。 不会有任何密码。
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎是题外话,因为它缺乏足够的信息来诊断问题。 更详细地描述您的问题或include a min
我是一名优秀的程序员,十分优秀!