或者它现在反过来了?
从我所听到的有些领域,C#证明比C++更快,但我从来没有勇气自己测试它.
你们中的任何一个人都可以详细解释这些差异,或者将我指向正确的地方以获取相关信息.
感谢C++ 11,我们收到了std::functionfunctor包装器系列.不幸的是,我一直只听到关于这些新增内容的不好的事情.最受欢迎的是它们非常慢.我对它进行了测试,与模板相比,它们真的很糟糕.
#include <iostream>
#include <functional>
#include <string>
#include <chrono>
template <typename F>
float calc1(F f) { return -1.0f * f(3.3f) + 666.0f; }
float calc2(std::function<float(float)> f) { return -1.0f * f(3.3f) + 666.0f; }
int main() {
using namespace std::chrono;
const auto tp1 = system_clock::now();
for (int i = 0; i < 1e8; ++i) {
calc1([](float arg){ return arg * 0.5f; });
}
const auto tp2 = high_resolution_clock::now();
const auto d = duration_cast<milliseconds>(tp2 - tp1);
std::cout << …Run Code Online (Sandbox Code Playgroud) 我有一种感觉,lambda的类型是一个函数指针.当我进行以下测试时,我发现它是错误的(演示).
#define LAMBDA [] (int i) -> long { return 0; }
int main ()
{
long (*pFptr)(int) = LAMBDA; // ok
auto pAuto = LAMBDA; // ok
assert(typeid(pFptr) == typeid(pAuto)); // assertion fails !
}
Run Code Online (Sandbox Code Playgroud)
上面的代码是否缺少任何一点?如果不是那么,typeof用auto关键字推导出的lambda表达式是什么?
编译器内联lambda函数是否可以提高效率,因为它可以使用简单的标准函数?
例如
std::vector<double> vd;
std::for_each(vd.begin(), vd.end(), [](const double d) {return d*d;});
Run Code Online (Sandbox Code Playgroud)
或者由于缺乏优化而导致效率下降?
第二个问题:我可以在哪里检查我使用的编译器是否优化了内联函数调用,这些函数被发送到算法?我的意思是,如果函数 - 而不是函数对象 - 被发送到算法,最后一个获取指向函数的指针,并且一些编译器优化指向内联函数的指针而其他编译器没有.
我刚刚学习了lambda表达式,并想知道使用时打印到控制台时表达式或常规函数是否会执行得更快cout.
我应该用吗?
// Lambda expression
auto helloWorld = []()
{
cout << "Hello World" << endl;
};
Run Code Online (Sandbox Code Playgroud)
要么
// Normal function
void helloWorld()
{
cout << "Hello World" << endl;
}
Run Code Online (Sandbox Code Playgroud)
注意:我仍然是新手程序员,所以请随时指出我可能犯的任何错误.我只能学习
谢谢
新的C++ 11标准支持lambda函数,我认为这是一个有用的功能.我知道C和C++标准彼此不同但我不明白为什么C11不支持lambda函数.我认为它可能有很多用途.
有没有理由为什么C11标准的开发人员选择不包含此功能?
这是我做的一个比较。np.argsort在由 1,000,000 个元素组成的 float32 ndarray 上计时。
In [1]: import numpy as np
In [2]: a = np.random.randn(1000000)
In [3]: a = a.astype(np.float32)
In [4]: %timeit np.argsort(a)
86.1 ms ± 1.59 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
Run Code Online (Sandbox Code Playgroud)
这是一个 C++ 程序执行相同的过程,但在引用此答案的向量上。
#include <iostream>
#include <vector>
#include <cstddef>
#include <algorithm>
#include <opencv2/opencv.hpp>
#include <numeric>
#include <utility>
int main()
{
std::vector<float> numbers;
for (int i = 0; i != 1000000; ++i) {
numbers.push_back((float)rand() …Run Code Online (Sandbox Code Playgroud) 背景
作为一种组织策略,我喜欢在复杂的函数中定义函数局部 lambda。它适用于封装多步逻辑、重复操作等(一般来说,函数适用的类型),但不会创建在使用范围之外可见的东西。这是约翰卡马克在他的关于内联代码优点的文章中阐述的风格的综合/替代品,因为它使所有东西都整齐地封装在它打算使用的函数中,同时还提供了一个(编译器识别的)名称来记录每个功能块。一个简单的、人为的例子可能看起来像这样(假设这里实际上发生了一些足够复杂的事情,值得使用这种风格):
void printSomeNumbers(void)
{
const auto printNumber = [](auto number) {
std::cout << number << std::endl; // Non-trivial logic (maybe formatting) would go here
};
printNumber(1);
printNumber(2.0);
}
Run Code Online (Sandbox Code Playgroud)
从语义上讲,这个函数的编译形式“应该”创建一个隐式定义的函子的实例,然后operator()()为每个提供的输入调用该函子,因为这就是在 C++ 中使用 lambda 的含义。然而,在优化的构建中,as-if 规则释放了编译器来内联一些东西,这意味着实际生成的代码可能只是内联 lambda 的内容并完全跳过定义/实例化函子。关于这种内联的讨论已经出现在过去的讨论中,这里和这里,以及其他地方。
题
在我找到的所有 lambda 内联问题和答案中,所提供的示例没有使用任何形式的lambda 捕获,而且它们在很大程度上也与将 lambda 作为参数传递给某物有关(即在std::for_each调用的上下文)。那么,我的问题是:编译器是否仍然可以内联捕获值的 lambda?更具体地说(因为我假设各种变量的生命周期在很大程度上影响了答案),编译器是否可以合理地内联一个仅在定义它的函数内部使用的 lambda,即使它捕获了一些东西(即局部变量)通过引用?
我的直觉是,内联应该是可能的,因为编译器可以完全了解所有代码和相关变量(包括它们相对于 lambda 的生命周期),但我并不乐观,我的汇编阅读技能也不是t 足够多地为我自己得到一个可靠的答案。
附加示例
以防万一我描述的特定用例不是很清楚,这里是上面 lambda 的一个修改版本,它利用了我描述的那种模式(再次,请忽略代码是人为的这一事实并且不必要地过于复杂):
void printSomeNumbers(void)
{
std::ostringstream ss;
const auto …Run Code Online (Sandbox Code Playgroud) 我想创建一些基本上应该包装它的参数的模板.该参数应该是一个任意的函数调用,它通过一些模板元编程魔法包含前缀和后缀代码.
我想用它如下:
auto result = try_call( some_vector.at(13) );
Run Code Online (Sandbox Code Playgroud)
并try_call会以某种方式定义,它周围包裹try..catch块some_vector.at(13).像这样的东西:
template<typename T>
// some template metaprogramming magic here
try {
auto value = // execute the parameter here, i.e. some_vector.at(13);
return std::experimental::optional<T>(value);
}
catch (std::exception&) {
return std::experimental::nullopt;
}
Run Code Online (Sandbox Code Playgroud)
有一篇关于Bjarne Stroustrup的论文,但这并不完全描述我需要什么,而且我无法找到解决这个问题的方法.
如果直接无法做到这一点,我现在正在考虑通过一个带有lambda的模板化函数来实现:
template<typename Func>
auto try_call(Func f) {
try {
return f();
} catch(std::exception&) {
return std::experimental::nullopt;
}
}
Run Code Online (Sandbox Code Playgroud)
但我不知道这是不是一个好主意.我想,lambda有一些开销吗?我想避免任何不必要的开销.
我想在C++中编写一个将lambda函数保存为成员变量的类.尽可能高效地做它会很棒.例如,我读了这个线程为什么编译器可以比普通函数更好地优化lambdas?因此我想避免使用函数指针.
到目前为止,我最好的解决方案如下:
template<typename F>
class LambdaClass {
private:
F lambdaFunc;
public:
LambdaClass(F &_lambdaFunc): lambdaFunc(_lambdaFunc) {}
};
Run Code Online (Sandbox Code Playgroud)
我会用这个类如下:
auto lambdaFunc = [](int _a) -> int { return _a; };
LambdaClass<decltype(lambdaFunc)> lambdaClassObject<decltype(lambdaFunc)>(lambdaFunc);
Run Code Online (Sandbox Code Playgroud)
在我看来,使用它看起来并不好玩.所以我首先感兴趣的是,如果编译器可以内联已保存成员lambda函数的调用,那么这个代码是否有效,以及如何编写这个代码更漂亮?
编辑:我正在使用C++ 11.
c++ ×9
lambda ×7
c++11 ×4
performance ×2
templates ×2
auto ×1
benchmarking ×1
c ×1
c# ×1
c++14 ×1
c++17 ×1
c11 ×1
function ×1
inline ×1
numpy ×1
optimization ×1
python ×1
std-function ×1
stl ×1
typeof ×1