7、代码性能优化建议
1、当确定函数没有异常的使用,使用noexcept
在 C++11 中,noexcept关键字用于表示函数不会抛出异常。使用noexcept的主要原因是为了提高代码的效率和性能。
在 C++中,函数的默认行为是可以抛出异常的。这意味着在函数内部如果发生了异常,程序会跳转到异常处理代码,并执行相应的处理逻辑。然而,这种异常处理机制会带来一定的性能开销,因为它涉及到栈的展开、内存的分配和释放等操作。
对于一些特定的函数,例如一些简单的计算函数或资源管理函数,我们可以事先确定它们不会抛出异常。在这种情况下,使用noexcept可以告诉编译器函数不会抛出异常,从而编译器可以对代码进行优化,省略一些不必要的异常处理开销。
使用noexcept的另一个好处是可以提高代码的可维护性。当函数被声明为noexcept时,我们明确地表示了函数不会抛出异常,这可以帮助开发者更好地理解函数的行为和边界条件。
需要注意的是,使用noexcept并不意味着函数就可以任意地忽略异常。如果函数内部确实发生了异常,而函数又没有提供适当的异常处理机制,那么程序可能会出现未定义的行为或直接崩溃。
总之,在 C++11 中使用noexcept关键字是为了在特定情况下提高代码的效率和性能,同时也可以提高代码的可维护性。但在使用noexcept时,仍然需要谨慎处理函数内部可能出现的异常情况。
2、emplace_back和push_back的区别
只有在以下情况下,emplace_back和push_back有区别
class Item { public: Item(int id, std::string name): id_(id), name_(std::move(name)) { std::cout << "Item(int, std::string)" << std::endl; } Item(const Item& rhs) : id_(rhs.id_), name_(rhs.name_) { std::cout << "Item(const Item&)" << std::endl; } Item(Item&& rhs) : id_(rhs.id_), name_(std::move(rhs.name_)) { std::cout << "Item(const Item&&)" << std::endl; } ~Item() {} private: int id_; std::string name_; }; int main() { //情况1 std::vector<Item> vec1; vec1.push_back({1,"zhao"}); //情况2 std::vector<Item> ve2; ve2.emplace_back(1,"zhao"); return 0; }
情况1和情况2相比较:
情况1:vec1.push_back({1,"zhao"});,会先调用构造函数,创建个临时对象,然后临时对象属于右值,将右值传递给push_back;
情况2:只调用构造函数,创建对象,直接传给emplace_back;
总结:在工作总大部分情况下,push_back和emplace_back是一样的,当是临时创建的对象,例如情况2,才使用emplace_back,但是emplace_back使用也是有风险的,这里暂不介绍。
111