在循环后面声明变量还是在循环里面声明变量? - 页 11

 
Vict:

我查了一下,原来没有https://en.cppreference.com/w/cpp/compiler_support 编译器完成模块,所以没有什么可看的。

仍然能够通过clang使用这些模块

// module
export module M;
export int f(int x) {
    return 2 + x;
}

// main.cc
import M;
int main() {
        for(int i = 0;  i < 1000000;  ++ i)
                f(5);
}

通过优化编译,循环根本没有被执行(即优化是在:翻译单元+半连接模块之间进行的,而不是像以前那样只有一个翻译单元)。没有任何LTO。我认为,标准的C++候选者将完全转移到模块上,这样就不会有问题:"为什么在这个带有裸露循环的人为例子上这么慢"。

 
Alexey Navoykov:

所以它似乎已经发现,即使在这种情况下,它每次都会分配和删除内存。


顺便说一下,我上次可能给出了错误的结果。 很可能是在x86模式下。现在我在x64模式下测试,C++的结果要好得多。

1) ~ 2000毫秒

2) ~ 200毫秒(它是3倍的速度)。

虽然我也把Studio更新到了最新的版本,但这肯定也影响了它,因为现在即使是x86也比以前的测试快。

好了,现在C++不那么可耻地输给了夏普。只输了3倍左右)

嗯,所以没有垃圾收集器,定义问题是什么?

我不是在谈论速度,我是在谈论内存
 
Alexey Navoykov ,事实证明,constexpr字符串和向量被拖入了c++20。也就是说,我们所有的测试将完全不需要一条指令来服务于一个字符串,例如分配内存等。(当然,如果符号不是来自早期时间的话)。酷。
 
Vict:
Alexey Navoykov ,事实证明,constexpr字符串和向量被拖入了C++20。也就是说,所有这些测试在维护字符串时根本不需要一条指令,例如分配内存等。(当然,如果符号不是来自早期时间的话)。酷。

是否有必要把所有的东西都明确标记为constexpr,或者它将自动检测到它?

在我看来,问题不在标准中,而在编译器中。 是否有什么东西阻止了它删掉不必要的东西? 特别奇怪的是,夏普编译器可以正常优化,而同一微软 的plus版本却不能。 虽然看起来它们应该有一个共同的基础(在优化此类结构方面)。

 
Alexey Navoykov:

是否有必要把所有的东西都明确标记为constexpr,或者它将自动检测到它?

std是自动的,字符串得到的是在编译时已知的字符串就足够了。用这个字符串进行的所有操作(搜索、替换......)在编译时都会是一样的(我怀疑sharp和mcl在编译时也会计算我们的例子)。计划是使所有的容器都成为constepxr。也就是说,它不再依赖于编译器的情绪,而是由标准保证,我们可以通过字符串解析来计算模板参数,比如说。这里有一个有趣的地方--原来new/delete现在也是constexpr(对于constexpr类型)?

在我看来,问题不在标准中,而在编译器中。 是否有什么东西阻止了它删除不必要的东西? 特别奇怪的是,夏普编译器可以正常优化,而同一微软公司 的plus版本却失败了,尽管它们似乎必须有一个共同的基础(在这种结构的优化方面)。

Plus在优化可能性方面有一个缺点--它只在一个翻译单元内(如果我们不使用LTO)。当然你可以在头文件上做整个std,但他们不这样做(因为编译时间?)带有模块的夏普在这方面更先进。但随着模块的出现,c++20也将很快解决这个问题。还计划将std移到那里(首先他们将调试模块,然后他们将写它)。但VS似乎已经在模块上做了std,你可以试试(留下上面的链接)。

但我仍然坚持--最好是在循环之后声明(好吧,如果它不是一个基本类型)。

 
Alexey Navoykov:

为了好奇,我决定在C#中也测试一下。 结果不仅在速度上几乎一样,而且工作起来也比C++快得多。

结果。

Sum: 894782460, Time: 69 ms.

总和: 894782460, 时间: 56 ms

这里有一个C++中的类似物。

总和: 894782460, 时间: 2947 ms

总和: 894782460, 时间: 684 ms

我在VS 2019中测试,所有的优化都已启用

去他妈的这样的C++程序)。

p.s. 在C#中,不同的测试结果有令人愉快的差异,但平均而言,两种变体的速度相同。

提示:在sharpe中,字符串是基本类型,在pluses中,它是一个用pluses写的类。在夏普变体中,字符串的分配只做一次,在正数中则是10e6次。最后,pluses更快,但你在写代码时需要聪明,而不是像波音公司的印度人那样做一个驼背。
 
SeriousRacoon:
提示:在sharpe中,字符串是基本类型,在pluses中,它是用pluses写的类。在夏普变体中,字符串的分配只做一次,在正数中--10e6次。其结果是,pluses更快,但你在写代码时需要打开你的大脑,而不是像波音公司的印度人那样做一个驼背。
不,这不是它的全部内容。我只是忘了,字符串有一个类,它是被分配的引用,而不是对象本身。 所以,这种形式的比较是不正确的
 

顺便说一下,说到优化。你想让编译器在这里优化一些东西吗?

mutex mtx;

void thread_0() {
        while (true) {
                do_task_0();
                {
                        lock_guard<mutex> lck{mtx};
                        do_task_1();
                }
                do_task_2();
                {
                        lock_guard<mutex> lck{mtx};
                        do_task_3();
                }
                do_task_4();
        {
}
void thread_1() {
        while (true) {
                do_task_5();
                {
                        lock_guard<mutex> lck{mtx};
                        do_task_6();
                }
                do_task_7();
                {
                        lock_guard<mutex> lck{mtx};
                        do_task_8();
                }
                do_task_9();
        {
}
 
Alexey Navoykov:
不,那里的观点是完全不同的。我只是忘记了字符串在那里是一个类,它是一个被分配的引用,而不是对象本身。 所以,这种形式的比较是不正确的
参考(指针)在哪里分配? 在加类字符串中? 你的意思是,缓冲区的选择和复制在那里进行。
 
SeriousRacoon:
引用(指针)分配在哪里? 在加类字符串中? 你是什么意思,是缓冲区的选择和复制。

他所说的是尖锐的

原因: