减少 std::bind 模板代码膨胀?
Reducing std::bind template code bloat?
我写了一个存储 std::function<void(void*)>
的对象,它作为参数传递给构造函数。该对象稍后会在将来的某个时间回调此 std::function。这已经实现并且运行良好。
在每个使用这个对象的class中,他们调用初始化列表中的构造函数,如下所示:
mCallbackObj(std::bind(&MyClass::MyFunc, this, _1))
但是,我发现每个包含此对象作为成员的 class 都将我的代码空间增加了 ~2K。由于可能有数百个地方将使用此对象,并且代码空间选项有限(这是嵌入式产品),因此每次使用 2k 的点击率是不可接受的。
一个有趣的观察是,如果 class 有第二个对象:
mCallbackObj2(std::bind(&MyClass::MyOtherFunc, this, _1))
这只会增加约 150 字节的代码空间 - 非常可以接受!只有当对象用于不同的 classes 时,我才看到 2K 命中。将 classes 全部放在一个 .cpp 文件中没有帮助 - 每个包含此对象的 class 仍然有 2k 命中。
我尝试过使用 extern template class std::function<void(void*)>;
,但这对 ROM 大小没有影响。
我正在使用 gcc 4.8。我喜欢使用 std::function
和 std::bind
,但即将放弃并切换到 class 方法指针。它们不会那么干净,但希望 ROM 效率更高。
在我放弃之前,是否有任何其他选项可以帮助减少我的模板代码空间膨胀?
我对此进行了深入研究并观看了 @John's video on std::function
. In the video,出于某些原因,STL 建议在 std::bind
上使用 lambda。
我尝试将代码转换为使用 Lambda,这正是上面 @Igor Tandetnik 推荐的。明显好很多。
mCallbackObj(std::bind(&MyClass::MyFunc, this, _1))
占用额外的 2,888 字节代码空间。而是使用
mCallbackObj([this](void *info){MyFunc(info);})
只占用额外的812字节!这要好得多,并且对于我的用例来说已经足够好了。对于不熟悉 std::bind 语法的 C++ 程序员,lambda 解决方案也更易于阅读。
更新-
在升级到 GCC 6.0 并调整我们的编译器标志后(我们之前并不总是传入 -O2),我重新测试了这个。
Lambda: 216 bytes
std::bind: 221 bytes
function pointer: 228 bytes
所有 3 个现在都更加合理。我们主要使用 lambda,因为一旦开发人员熟悉语法,它们最容易阅读。
我写了一个存储 std::function<void(void*)>
的对象,它作为参数传递给构造函数。该对象稍后会在将来的某个时间回调此 std::function。这已经实现并且运行良好。
在每个使用这个对象的class中,他们调用初始化列表中的构造函数,如下所示:
mCallbackObj(std::bind(&MyClass::MyFunc, this, _1))
但是,我发现每个包含此对象作为成员的 class 都将我的代码空间增加了 ~2K。由于可能有数百个地方将使用此对象,并且代码空间选项有限(这是嵌入式产品),因此每次使用 2k 的点击率是不可接受的。
一个有趣的观察是,如果 class 有第二个对象:
mCallbackObj2(std::bind(&MyClass::MyOtherFunc, this, _1))
这只会增加约 150 字节的代码空间 - 非常可以接受!只有当对象用于不同的 classes 时,我才看到 2K 命中。将 classes 全部放在一个 .cpp 文件中没有帮助 - 每个包含此对象的 class 仍然有 2k 命中。
我尝试过使用 extern template class std::function<void(void*)>;
,但这对 ROM 大小没有影响。
我正在使用 gcc 4.8。我喜欢使用 std::function
和 std::bind
,但即将放弃并切换到 class 方法指针。它们不会那么干净,但希望 ROM 效率更高。
在我放弃之前,是否有任何其他选项可以帮助减少我的模板代码空间膨胀?
我对此进行了深入研究并观看了 @John's video on std::function
. In the video,出于某些原因,STL 建议在 std::bind
上使用 lambda。
我尝试将代码转换为使用 Lambda,这正是上面 @Igor Tandetnik 推荐的。明显好很多。
mCallbackObj(std::bind(&MyClass::MyFunc, this, _1))
占用额外的 2,888 字节代码空间。而是使用
mCallbackObj([this](void *info){MyFunc(info);})
只占用额外的812字节!这要好得多,并且对于我的用例来说已经足够好了。对于不熟悉 std::bind 语法的 C++ 程序员,lambda 解决方案也更易于阅读。
更新-
在升级到 GCC 6.0 并调整我们的编译器标志后(我们之前并不总是传入 -O2),我重新测试了这个。
Lambda: 216 bytes
std::bind: 221 bytes
function pointer: 228 bytes
所有 3 个现在都更加合理。我们主要使用 lambda,因为一旦开发人员熟悉语法,它们最容易阅读。