本帖最后由 Ph-苯 于 2022-12-9 13:52 编辑
书接上回:暗地里到底没了多少?🧐
大雾
Kotlin (JVM):
C++:
经群友提醒,在C++用内联再试了一遍:
经群友和坛友提醒,对第二版C++代码开启O2优化,结果控制台输出变成0了……把循环次数改成0xffffffffffffffff,输出还是0。把第一版C++代码启用O2优化,循环次数也改成0xffffffffffffffff,输出也变成0了。我怀疑这部分代码直接被优化没了。
刚刚发现C++我写的赋值运算符函数是错的,导致其没有赋值。我把x和y都改成非const,并使用默认的赋值运算符函数:
开O2优化,控制台输出:0
不出所料,O2优化把无副作用的循环给优化掉了……
我把主函数改成这样:
O2优化果然了得。
书接上回:暗地里到底没了多少?🧐
大雾
Kotlin (JVM):
控制台输出:280
C++:
控制台输出:2379
经群友提醒,在C++用内联再试了一遍:
控制台输出:1397
经群友和坛友提醒,对第二版C++代码开启O2优化,结果控制台输出变成0了……把循环次数改成0xffffffffffffffff,输出还是0。把第一版C++代码启用O2优化,循环次数也改成0xffffffffffffffff,输出也变成0了。我怀疑这部分代码直接被优化没了。
刚刚发现C++我写的赋值运算符函数是错的,导致其没有赋值。我把x和y都改成非const,并使用默认的赋值运算符函数:
不开O2优化,控制台输出:2484
开O2优化,控制台输出:0
不出所料,O2优化把无副作用的循环给优化掉了……
我把主函数改成这样:
控制台输出第一行:23
O2优化果然了得。
本帖最后由 src_resources 于 2022-12-9 13:11 编辑
因为C++是在C语言的基础上引入了很多更先进的语法和功能,因此编译器处理后,因为要转换为与C语言对等的可执行二进制文件,因此可能会塞很多未知的等效代码段进去以达到目的,进而造成不必要的延时。
曾经在Ubuntu上用g++试过一次,加上-S选项看了等效汇编代码后和意想当中的完全是两面,本来一个类似于楼主这样的简单for循环,被g++,只需要一些cmp和jnz等指令就可以实现,硬是被它塞了很多自己的segment,再调用对应的预设代码段来实现。还有很多奇怪的变量名只有编译器自己能懂,我看不懂,像极了IT公司里面看同事代码的样子。
另外楼主也可以尝试开启 -O2 选项,再看看用时是多少。
因为C++是在C语言的基础上引入了很多更先进的语法和功能,因此编译器处理后,因为要转换为与C语言对等的可执行二进制文件,因此可能会塞很多未知的等效代码段进去以达到目的,进而造成不必要的延时。
曾经在Ubuntu上用g++试过一次,加上-S选项看了等效汇编代码后和意想当中的完全是两面,本来一个类似于楼主这样的简单for循环,被g++,只需要一些cmp和jnz等指令就可以实现,硬是被它塞了很多自己的segment,再调用对应的预设代码段来实现。还有很多奇怪的变量名只有编译器自己能懂,我看不懂,像极了IT公司里面看同事代码的样子。

另外楼主也可以尝试开启 -O2 选项,再看看用时是多少。
src_resources 发表于 2022-12-9 13:10
因为C++是在C语言的基础上引入了很多更先进的语法和功能,因此编译器处理后,因为要转换为与C语言对等的可 ...
开了O2,结果变成0了……改成循环0xffffffffffffffff次,还是0……
本帖最后由 w6vDqw 于 2022-12-11 11:43 编辑
我的评价是,基于栈操作的语言,和用指针直接操作内存的语言比,这就是找虐。
你觉得C++慢肯定是因为你没做好优化。
粗略看了一眼,这代码C和C++混用,这就没意思了。要用C++就要有C++的样子。
我的评价是,基于栈操作的语言,和用指针直接操作内存的语言比,这就是找虐。
你觉得C++慢肯定是因为你没做好优化。
粗略看了一眼,这代码C和C++混用,这就没意思了。要用C++就要有C++的样子。
所以,优化是一点,JE版慢是没有做好算法优化就被BE吊打。BE优化好但是因为渲染龙的遗留问题所以光影直接被集体枪毙()
兼容又是另一个问题了
兼容又是另一个问题了
w6vDqw 发表于 2022-12-9 13:46
我的评价是,基于数栈操作的语言,和用指针直接操作内存的语言比,这就是找虐。
你觉得C++慢肯定是因为你没 ...
确实,C++开了编译器优化后直接把循环给优化没了,确实快了。
Ph-苯 发表于 2022-12-9 13:31
开了O2,结果变成0了……改成循环0xffffffffffffffff次,还是0……
看了一下代码,for循环指定了100000000次,main函数里调用的函数也只进行了简单的加减和移位操作;定义的变量v2i 也只是简单的调用了一下这些运算函数,并未实际使用。
估计是编译器直接把for循环优化了,省去了与v2i变量相关的代码,时间复杂度也直接从O(n)降到了O(1)。

gmc_awa 发表于 2022-12-9 13:49
所以,优化是一点,JE版慢是没有做好算法优化就被BE吊打。BE优化好但是因为渲染龙的遗留问题所以光影直接被 ...
JE确实很多该有算法的地方都没有,BE就不知道了。
Ph-苯 发表于 2022-12-9 13:53
确实,C++开了编译器优化后直接把循环给优化没了,确实快了。
那是因为这破玩意被编译器丢到了CPU的L1里面了,所以调用速度超乎你想象。
src_resources 发表于 2022-12-9 13:55
看了一下代码,for循环指定了100000000次,main函数里调用的函数也只进行了简单的加减和移位操作;定义的 ...
我改了,在最后打印v2i,这样就不会被整个优化掉了。
w6vDqw 发表于 2022-12-9 13:57
那是因为这破玩意被编译器丢到了CPU的L1里面了,所以调用速度超乎你想象。 ...
这段循环确实是被C++编译器直接删掉了,这点可以用-S编译选项编译时看到
w6vDqw 发表于 2022-12-9 13:46
我的评价是,基于数栈操作的语言,和用指针直接操作内存的语言比,这就是找虐。
你觉得C++慢肯定是因为你没 ...
在变量不太多不太大并且没有取地址运算的情况下,Java和C++都是直接在寄存器中运算,并不会操作内存
当然我不知道你在说什么,上面这段代码哪有指针???
洞穴夜莺 发表于 2022-12-9 14:30
在变量不太多不太大并且没有取地址运算的情况下,Java和C++都是直接在寄存器中运算,并不会操作内存
当然 ...
不直接操作为什么会慢,这是问题。
java就是比c++快一些
w6vDqw 发表于 2022-12-9 13:46
我的评价是,基于数栈操作的语言,和用指针直接操作内存的语言比,这就是找虐。
你觉得C++慢肯定是因为你没 ...
什么叫C和C++混用?
你可就别吹了java这辈子都不如他爹C语言(不是c++)

本帖最后由 Ph-苯 于 2022-12-10 13:17 编辑
@w6vDqw 不是说printf比cout更快吗?不过开了O2优化估计也差不多了。
@w6vDqw 不是说printf比cout更快吗?不过开了O2优化估计也差不多了。
Ph-苯 发表于 2022-12-10 07:02
不是说printf比cout更快吗?不过开了O2优化估计也差不多了。
?大佬为啥自己占楼!
Qhxss 发表于 2022-12-10 07:07
?大佬为啥自己占楼!
有人用评分回复我,我没法引用他。
Ph-苯 发表于 2022-12-10 07:07
有人用评分回复我,我没法引用他。
那你至少艾特一下吧,你作为版主这样不好吧
Qhxss 发表于 2022-12-10 11:07
那你至少艾特一下吧,你作为版主这样不好吧
噢,对哦,还可以at,多谢提醒。
本帖最后由 w6vDqw 于 2022-12-10 17:03 编辑
我的算法也不行。
时间复杂度高达o(16*n),运行完之后优势全无。
也是,我根本就不是很会算法,所以……
复制代码
Ph-苯 发表于 2022-12-10 07:02
@w6vDqw 不是说printf比cout更快吗?不过开了O2优化估计也差不多了。
我的算法也不行。
时间复杂度高达o(16*n),运行完之后优势全无。
也是,我根本就不是很会算法,所以……
- //
- // main.c
- // ctest
- //
- // Created by Merry on 2022/12/10.
- //
- #include <stdio.h>
- #include <time.h>
- void getx(unsigned long long *v){
- *v=*v>>32;
- }
- //操作指针做位移运算。
- void gety(unsigned long long *v){
- *v=*v<<32;
- }
- //由于直接通过指针操作数据,因此再次操作指针做位移运算。
- void plus(unsigned long long *v1,unsigned long long *v2){
- getx(v1);
- getx(v2);
- unsigned long long x=*v1+*v2;
- gety(v1);
- gety(v2);
- unsigned long long y=*v1+*v2;
- *v1=((unsigned long long)x<<32)|y;
- }
- void minus(unsigned long long *v1,unsigned long long *v2){
- getx(v1);
- getx(v2);
- unsigned long long x=*v1-*v2;
- gety(v1);
- gety(v2);
- unsigned long long y=*v1-*v2;
- *v2=((unsigned long long)x<<32)|y;
- }
- int main(void){
- int x=1,y=2;
- unsigned long long v,*v1=NULL,*v2=NULL;
- v=((unsigned long long)x<<32|y);
- v2=&v;
- v1=v2;
- // 定义数据,做好准备工作。操作指针做位与运算。
- struct timespec ts;
- timespec_get(&ts,TIME_UTC);
- long ms=(ts.tv_nsec/1000000);
- long s=(ts.tv_sec);
- // 获取开始时间。
- for(int i=0;i<100000000;i++){
- plus(v1,v2);
- minus(v1,v2);
- }
- // 循环一亿次。
- timespec_get(&ts,TIME_UTC);
- long ms1=(ts.tv_nsec/1000000);
- long s1=(ts.tv_sec);
- // 获取结束时间。
- printf("%lo\n",ms);
- printf("%lo\n",s);
- printf("%lo\n",ms1);
- printf("%lo\n",s1);
- // 打印时间。
- return 0;
- }
java就是比c++快一些
az我感觉c语言更快awa 仅代表自己
w6vDqw 发表于 2022-12-10 15:58
我的算法也不行。
时间复杂度高达o(16*n),运行完之后优势全无。
也是,我根本就不是很会算法,所以……
我严重怀疑你没有测试过你plus和minus算出来的值到底对不对
你写的这两个函数都可以优化为
- void minus(unsigned long long *v1,unsigned long long *v2){
- *v2=0;
- }
Python: 你们继续打架,优化到能有你们这程度的时候已经是几十年后了。
——Python 饮了一口 Java,如是说道
——Python 饮了一口 Java,如是说道
洞穴夜莺 发表于 2022-12-11 09:40
我严重怀疑你没有测试过你plus和minus算出来的值到底对不对
你写的这两个函数都可以优化为至于为什么计算 ...
是0这个我还是知道的。
可以的大佬能不能带带我
洞穴夜莺 发表于 2022-12-11 09:40
我严重怀疑你没有测试过你plus和minus算出来的值到底对不对
你写的这两个函数都可以优化为至于为什么计算 ...
对哦,我之前还没发现这个函数这么离谱。
名副其实 发表于 2022-12-11 09:41
Python: 你们继续打架,优化到能有你们这程度的时候已经是几十年后了。
——Python 饮了一口 Java,如是说 ...
Groovy:哪天我哪怕能像 Kotlin 一样快我就封神了。
Python 虽然也可以预编译字节码,但毕竟人家是动态语言,恨不得运行时去匹配令牌。
Groovy 同理,好像是所有的令牌都在运行时找(没细研究过,
虽然没看懂
懂了,所以java天下第一(bushi)
teddyxlandlee 发表于 2022-12-17 20:54
Groovy:哪天我哪怕能像 Kotlin 一样快我就封神了。
Python 虽然也可以预编译字节码,但毕竟人家是动态 ...
kt也不慢吧?
Ph-苯 发表于 2022-12-18 01:24
kt也不慢吧?
kt确实不慢,但是总感觉kt生成出的字节码很奇怪,比如会整出一些从来没用过的临时变量(这与inline内部库有关)
teddyxlandlee 发表于 2022-12-18 07:34
kt确实不慢,但是总感觉kt生成出的字节码很奇怪,比如会整出一些从来没用过的临时变量(这与inline内部库 ...
kt生成的字节码甚至能让ij idea的反编译器报错,这不是一般字节码能做到的。
Ph-苯 发表于 2022-12-18 14:46
kt生成的字节码甚至能让ij idea的反编译器报错,这不是一般字节码能做到的。 ...
害,我手搓的东西照样能崩fernflower
咱就是说,趁早润cfr,有些语法糖能给你反编译出来(foreach, 新的switch-case等)
——然而面对不按套路出牌的kotlinc你还是拿它没办法
——面对proguard优化轰炸,它甚至能给你蹦出几个void declaration
毕竟字节码里一些attribute是vm下不能错的(Code, StackMapTable, ConstantValue……)但有些错了也不要紧(AnnotationDefault, RuntimeInvisibleAnnotation, LocalVariable*Table……),后者是可以用来欺骗反编译器的。
啥?爱用 SWAP?爱用 DUP 和 POP?
fernflower: Object var10000;
Java不正是C加加的升级版吗?
teddyxlandlee 发表于 2022-12-18 15:31
害,我手搓的东西照样能崩fernflower
咱就是说,趁早润cfr,有些语法糖能给你反编译出来(foreach, 新的s ...
什么手搓的东西能崩fernflower?我还没搞懂原理。
6355273 发表于 2022-12-18 15:38
Java不正是C加加的升级版吗?
不是啊,java没有这么宣称过,而且java比c++少了很多特性。
Ph-苯 发表于 2022-12-19 20:06
什么手搓的东西能崩fernflower?我还没搞懂原理。
崩倒不至于,但起码会生成错误得以至于无法编译的代码
最简单的例子:相同的local variable(只要我把变量表属性一扔,就恢复正常)
稍微麻烦一点的:自定义invokedynamic,或者比如把 lcmp 运算结果当 int 使
以及其它 fernflower 不认识的语法糖,虽说不一定能生成错误的代码,但一定会降低可读性——毕竟 fernflower 为数不多的语法糖反编译(如 switch-case String)都是基于 javac 的尿性来的
teddyxlandlee 发表于 2022-12-19 20:10
崩倒不至于,但起码会生成错误得以至于无法编译的代码
最简单的例子:相同的local variable(只要我把变 ...
这些能让fernflower错误反编译的字节码是由正常源代码编译生成的,还是直接对着字节码修改后的?
Ph-苯 发表于 2022-12-19 20:15
这些能让fernflower错误反编译的字节码是由正常源代码编译生成的,还是直接对着字节码修改后的? ...
肯定是改了字节码之后的嘛
teddyxlandlee 发表于 2022-12-19 21:49
肯定是改了字节码之后的嘛
改了字节码,那肯定很容易就出错吧。