Skip to content

Commit af6218f

Browse files
authored
fix(clang-tidy): Apply performance fixes from clang-tidy (#3046)
* Apply performance fixes from clang-tidy * 2nd Round of Perf Optimizations * 3rd round of fixes & handle false-positive * Apply missing fix and clang-format * Apply reviewer comment
1 parent 79178e7 commit af6218f

File tree

10 files changed

+106
-92
lines changed

10 files changed

+106
-92
lines changed

.clang-tidy

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,8 @@ modernize-use-auto,
1010
modernize-use-emplace,
1111
'
1212

13+
CheckOptions:
14+
- key: performance-unnecessary-value-param.AllowedTypes
15+
value: 'exception_ptr$;'
16+
1317
HeaderFilterRegex: 'pybind11/.*h'

include/pybind11/buffer_info.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,9 @@ struct buffer_info {
9191
buffer_info(const buffer_info &) = delete;
9292
buffer_info& operator=(const buffer_info &) = delete;
9393

94-
buffer_info(buffer_info &&other) {
95-
(*this) = std::move(other);
96-
}
94+
buffer_info(buffer_info &&other) noexcept { (*this) = std::move(other); }
9795

98-
buffer_info& operator=(buffer_info &&rhs) {
96+
buffer_info &operator=(buffer_info &&rhs) noexcept {
9997
ptr = rhs.ptr;
10098
itemsize = rhs.itemsize;
10199
size = rhs.size;

include/pybind11/cast.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,7 +1064,9 @@ struct kw_only {};
10641064
struct pos_only {};
10651065

10661066
template <typename T>
1067-
arg_v arg::operator=(T &&value) const { return {std::move(*this), std::forward<T>(value)}; }
1067+
arg_v arg::operator=(T &&value) const {
1068+
return {*this, std::forward<T>(value)};
1069+
}
10681070

10691071
/// Alias for backward compatibility -- to be removed in version 2.0
10701072
template <typename /*unused*/> using arg_t = arg_v;
@@ -1286,7 +1288,7 @@ class unpacking_collector {
12861288
"may be passed via py::arg() to a python function call. "
12871289
"(compile in debug mode for details)");
12881290
}
1289-
[[noreturn]] static void nameless_argument_error(std::string type) {
1291+
[[noreturn]] static void nameless_argument_error(const std::string &type) {
12901292
throw type_error("Got kwargs without a name of type '" + type + "'; only named "
12911293
"arguments may be passed via py::arg() to a python function call. ");
12921294
}
@@ -1295,7 +1297,7 @@ class unpacking_collector {
12951297
"(compile in debug mode for details)");
12961298
}
12971299

1298-
[[noreturn]] static void multiple_values_error(std::string name) {
1300+
[[noreturn]] static void multiple_values_error(const std::string &name) {
12991301
throw type_error("Got multiple values for keyword argument '" + name + "'");
13001302
}
13011303

@@ -1304,7 +1306,8 @@ class unpacking_collector {
13041306
"(compile in debug mode for details)");
13051307
}
13061308

1307-
[[noreturn]] static void argument_cast_error(std::string name, std::string type) {
1309+
[[noreturn]] static void argument_cast_error(const std::string &name,
1310+
const std::string &type) {
13081311
throw cast_error("Unable to convert call argument '" + name
13091312
+ "' of type '" + type + "' to Python object");
13101313
}

include/pybind11/eval.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
#pragma once
1313

14+
#include <utility>
15+
1416
#include "pybind11.h"
1517

1618
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
@@ -43,7 +45,7 @@ enum eval_mode {
4345
};
4446

4547
template <eval_mode mode = eval_expr>
46-
object eval(str expr, object global = globals(), object local = object()) {
48+
object eval(const str &expr, object global = globals(), object local = object()) {
4749
if (!local)
4850
local = global;
4951

@@ -75,8 +77,8 @@ object eval(const char (&s)[N], object global = globals(), object local = object
7577
return eval<mode>(expr, global, local);
7678
}
7779

78-
inline void exec(str expr, object global = globals(), object local = object()) {
79-
eval<eval_statements>(expr, global, local);
80+
inline void exec(const str &expr, object global = globals(), object local = object()) {
81+
eval<eval_statements>(expr, std::move(global), std::move(local));
8082
}
8183

8284
template <size_t N>

include/pybind11/iostream.h

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@
1111

1212
#include "pybind11.h"
1313

14-
#include <streambuf>
15-
#include <ostream>
16-
#include <string>
17-
#include <memory>
18-
#include <iostream>
14+
#include <algorithm>
1915
#include <cstring>
16+
#include <iostream>
2017
#include <iterator>
21-
#include <algorithm>
18+
#include <memory>
19+
#include <ostream>
20+
#include <streambuf>
21+
#include <string>
22+
#include <utility>
2223

2324
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
2425
PYBIND11_NAMESPACE_BEGIN(detail)
@@ -117,11 +118,8 @@ class pythonbuf : public std::streambuf {
117118
}
118119

119120
public:
120-
121-
pythonbuf(object pyostream, size_t buffer_size = 1024)
122-
: buf_size(buffer_size),
123-
d_buffer(new char[buf_size]),
124-
pywrite(pyostream.attr("write")),
121+
pythonbuf(const object &pyostream, size_t buffer_size = 1024)
122+
: buf_size(buffer_size), d_buffer(new char[buf_size]), pywrite(pyostream.attr("write")),
125123
pyflush(pyostream.attr("flush")) {
126124
setp(d_buffer.get(), d_buffer.get() + buf_size - 1);
127125
}
@@ -168,9 +166,8 @@ class scoped_ostream_redirect {
168166
detail::pythonbuf buffer;
169167

170168
public:
171-
scoped_ostream_redirect(
172-
std::ostream &costream = std::cout,
173-
object pyostream = module_::import("sys").attr("stdout"))
169+
scoped_ostream_redirect(std::ostream &costream = std::cout,
170+
const object &pyostream = module_::import("sys").attr("stdout"))
174171
: costream(costream), buffer(pyostream) {
175172
old = costream.rdbuf(&buffer);
176173
}
@@ -199,10 +196,9 @@ class scoped_ostream_redirect {
199196
\endrst */
200197
class scoped_estream_redirect : public scoped_ostream_redirect {
201198
public:
202-
scoped_estream_redirect(
203-
std::ostream &costream = std::cerr,
204-
object pyostream = module_::import("sys").attr("stderr"))
205-
: scoped_ostream_redirect(costream,pyostream) {}
199+
scoped_estream_redirect(std::ostream &costream = std::cerr,
200+
const object &pyostream = module_::import("sys").attr("stderr"))
201+
: scoped_ostream_redirect(costream, pyostream) {}
206202
};
207203

208204

@@ -261,9 +257,10 @@ PYBIND11_NAMESPACE_END(detail)
261257
m.noisy_function_with_error_printing()
262258
263259
\endrst */
264-
inline class_<detail::OstreamRedirect> add_ostream_redirect(module_ m, std::string name = "ostream_redirect") {
265-
return class_<detail::OstreamRedirect>(m, name.c_str(), module_local())
266-
.def(init<bool,bool>(), arg("stdout")=true, arg("stderr")=true)
260+
inline class_<detail::OstreamRedirect>
261+
add_ostream_redirect(module_ m, const std::string &name = "ostream_redirect") {
262+
return class_<detail::OstreamRedirect>(std::move(m), name.c_str(), module_local())
263+
.def(init<bool, bool>(), arg("stdout") = true, arg("stderr") = true)
267264
.def("__enter__", &detail::OstreamRedirect::enter)
268265
.def("__exit__", [](detail::OstreamRedirect &self_, args) { self_.exit(); });
269266
}

include/pybind11/numpy.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,10 +164,10 @@ struct npy_api {
164164
NPY_ULONG_, NPY_ULONGLONG_, NPY_UINT_),
165165
};
166166

167-
typedef struct {
167+
struct PyArray_Dims {
168168
Py_intptr_t *ptr;
169169
int len;
170-
} PyArray_Dims;
170+
};
171171

172172
static npy_api& get() {
173173
static npy_api api = lookup();

include/pybind11/pybind11.h

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1412,15 +1412,15 @@ class class_ : public detail::generic_type {
14121412

14131413
template <typename D, typename... Extra>
14141414
class_ &def_readwrite_static(const char *name, D *pm, const Extra& ...extra) {
1415-
cpp_function fget([pm](object) -> const D &{ return *pm; }, scope(*this)),
1416-
fset([pm](object, const D &value) { *pm = value; }, scope(*this));
1415+
cpp_function fget([pm](const object &) -> const D & { return *pm; }, scope(*this)),
1416+
fset([pm](const object &, const D &value) { *pm = value; }, scope(*this));
14171417
def_property_static(name, fget, fset, return_value_policy::reference, extra...);
14181418
return *this;
14191419
}
14201420

14211421
template <typename D, typename... Extra>
14221422
class_ &def_readonly_static(const char *name, const D *pm, const Extra& ...extra) {
1423-
cpp_function fget([pm](object) -> const D &{ return *pm; }, scope(*this));
1423+
cpp_function fget([pm](const object &) -> const D & { return *pm; }, scope(*this));
14241424
def_property_readonly_static(name, fget, return_value_policy::reference, extra...);
14251425
return *this;
14261426
}
@@ -1671,30 +1671,36 @@ struct enum_base {
16711671
}, name("__members__")), none(), none(), ""
16721672
);
16731673

1674-
#define PYBIND11_ENUM_OP_STRICT(op, expr, strict_behavior) \
1675-
m_base.attr(op) = cpp_function( \
1676-
[](object a, object b) { \
1677-
if (!type::handle_of(a).is(type::handle_of(b))) \
1678-
strict_behavior; \
1679-
return expr; \
1680-
}, \
1681-
name(op), is_method(m_base), arg("other"))
1682-
1683-
#define PYBIND11_ENUM_OP_CONV(op, expr) \
1684-
m_base.attr(op) = cpp_function( \
1685-
[](object a_, object b_) { \
1686-
int_ a(a_), b(b_); \
1687-
return expr; \
1688-
}, \
1689-
name(op), is_method(m_base), arg("other"))
1690-
1691-
#define PYBIND11_ENUM_OP_CONV_LHS(op, expr) \
1692-
m_base.attr(op) = cpp_function( \
1693-
[](object a_, object b) { \
1694-
int_ a(a_); \
1695-
return expr; \
1696-
}, \
1697-
name(op), is_method(m_base), arg("other"))
1674+
#define PYBIND11_ENUM_OP_STRICT(op, expr, strict_behavior) \
1675+
m_base.attr(op) = cpp_function( \
1676+
[](const object &a, const object &b) { \
1677+
if (!type::handle_of(a).is(type::handle_of(b))) \
1678+
strict_behavior; \
1679+
return expr; \
1680+
}, \
1681+
name(op), \
1682+
is_method(m_base), \
1683+
arg("other"))
1684+
1685+
#define PYBIND11_ENUM_OP_CONV(op, expr) \
1686+
m_base.attr(op) = cpp_function( \
1687+
[](const object &a_, const object &b_) { \
1688+
int_ a(a_), b(b_); \
1689+
return expr; \
1690+
}, \
1691+
name(op), \
1692+
is_method(m_base), \
1693+
arg("other"))
1694+
1695+
#define PYBIND11_ENUM_OP_CONV_LHS(op, expr) \
1696+
m_base.attr(op) = cpp_function( \
1697+
[](const object &a_, const object &b) { \
1698+
int_ a(a_); \
1699+
return expr; \
1700+
}, \
1701+
name(op), \
1702+
is_method(m_base), \
1703+
arg("other"))
16981704

16991705
if (is_convertible) {
17001706
PYBIND11_ENUM_OP_CONV_LHS("__eq__", !b.is_none() && a.equal(b));
@@ -2054,7 +2060,7 @@ exception<CppException> &register_exception(handle scope,
20542060
}
20552061

20562062
PYBIND11_NAMESPACE_BEGIN(detail)
2057-
PYBIND11_NOINLINE inline void print(tuple args, dict kwargs) {
2063+
PYBIND11_NOINLINE inline void print(const tuple &args, const dict &kwargs) {
20582064
auto strings = tuple(args.size());
20592065
for (size_t i = 0; i < args.size(); ++i) {
20602066
strings[i] = str(args[i]);

include/pybind11/pytypes.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ class accessor : public object_api<accessor<Policy>> {
503503
public:
504504
accessor(handle obj, key_type key) : obj(obj), key(std::move(key)) { }
505505
accessor(const accessor &) = default;
506-
accessor(accessor &&) = default;
506+
accessor(accessor &&) noexcept = default;
507507

508508
// accessor overload required to override default assignment operator (templates are not allowed
509509
// to replace default compiler-generated assignments).
@@ -1508,7 +1508,7 @@ class memoryview : public object {
15081508
detail::any_container<ssize_t> shape,
15091509
detail::any_container<ssize_t> strides) {
15101510
return memoryview::from_buffer(
1511-
const_cast<void*>(ptr), itemsize, format, shape, strides, true);
1511+
const_cast<void *>(ptr), itemsize, format, std::move(shape), std::move(strides), true);
15121512
}
15131513

15141514
template<typename T>

include/pybind11/stl.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,13 @@ template <typename Type, typename Value> struct list_caster {
159159
}
160160

161161
private:
162-
template <typename T = Type,
163-
enable_if_t<std::is_same<decltype(std::declval<T>().reserve(0)), void>::value, int> = 0>
164-
void reserve_maybe(sequence s, Type *) { value.reserve(s.size()); }
165-
void reserve_maybe(sequence, void *) { }
162+
template <
163+
typename T = Type,
164+
enable_if_t<std::is_same<decltype(std::declval<T>().reserve(0)), void>::value, int> = 0>
165+
void reserve_maybe(const sequence &s, Type *) {
166+
value.reserve(s.size());
167+
}
168+
void reserve_maybe(const sequence &, void *) {}
166169

167170
public:
168171
template <typename T>

include/pybind11/stl_bind.h

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,11 @@ void vector_modifiers(enable_if_t<is_copy_constructible<typename Vector::value_t
128128
arg("x"),
129129
"Add an item to the end of the list");
130130

131-
cl.def(init([](iterable it) {
131+
cl.def(init([](const iterable &it) {
132132
auto v = std::unique_ptr<Vector>(new Vector());
133133
v->reserve(len_hint(it));
134134
for (handle h : it)
135-
v->push_back(h.cast<T>());
135+
v->push_back(h.cast<T>());
136136
return v.release();
137137
}));
138138

@@ -151,27 +151,28 @@ void vector_modifiers(enable_if_t<is_copy_constructible<typename Vector::value_t
151151
"Extend the list by appending all the items in the given list"
152152
);
153153

154-
cl.def("extend",
155-
[](Vector &v, iterable it) {
156-
const size_t old_size = v.size();
157-
v.reserve(old_size + len_hint(it));
158-
try {
159-
for (handle h : it) {
160-
v.push_back(h.cast<T>());
161-
}
162-
} catch (const cast_error &) {
163-
v.erase(v.begin() + static_cast<typename Vector::difference_type>(old_size), v.end());
164-
try {
165-
v.shrink_to_fit();
166-
} catch (const std::exception &) {
167-
// Do nothing
168-
}
169-
throw;
170-
}
171-
},
172-
arg("L"),
173-
"Extend the list by appending all the items in the given list"
174-
);
154+
cl.def(
155+
"extend",
156+
[](Vector &v, const iterable &it) {
157+
const size_t old_size = v.size();
158+
v.reserve(old_size + len_hint(it));
159+
try {
160+
for (handle h : it) {
161+
v.push_back(h.cast<T>());
162+
}
163+
} catch (const cast_error &) {
164+
v.erase(v.begin() + static_cast<typename Vector::difference_type>(old_size),
165+
v.end());
166+
try {
167+
v.shrink_to_fit();
168+
} catch (const std::exception &) {
169+
// Do nothing
170+
}
171+
throw;
172+
}
173+
},
174+
arg("L"),
175+
"Extend the list by appending all the items in the given list");
175176

176177
cl.def("insert",
177178
[](Vector &v, DiffType i, const T &x) {
@@ -400,7 +401,7 @@ void vector_buffer_impl(Class_& cl, std::true_type) {
400401
return buffer_info(v.data(), static_cast<ssize_t>(sizeof(T)), format_descriptor<T>::format(), 1, {v.size()}, {sizeof(T)});
401402
});
402403

403-
cl.def(init([](buffer buf) {
404+
cl.def(init([](const buffer &buf) {
404405
auto info = buf.request();
405406
if (info.ndim != 1 || info.strides[0] % static_cast<ssize_t>(sizeof(T)))
406407
throw type_error("Only valid 1D buffers can be copied to a vector");

0 commit comments

Comments
 (0)