前言写一道 CF 题的时候,算法明明是正确的,却一直都 TLE。最后把一个 long long
类型的数组改成了 int
,竟然就 AC 了。。
这不禁引发了我的思考,int
与 long long
的运算速度不一样吗?
不严谨测试由于本菜鸡并没有什么计算机基础原理的知识,只好做了一个测试。当然,这个测试其实很不严谨,没有很大的参考价值。我也就图一乐,哈哈哈哈哈
测试环境电脑:Lenovo Yoga 14sACH 2021 系统:Windows 11 25163.1010 CPU:AMD Ryzen 7 5800H with Radeon Graphics (16) @ 3.200GHz RAM:16.0 GB 编译器:GCC 11.2.0 代码仅仅是为了图一乐, 我第一次使用了 Google Benchmark 这一工具。其实挺好上手的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <benchmark/benchmark.h>
using namespace benchmark ;
static void int_add ( State & state ) {
int a = std :: rand (), b = std :: rand (), c = 0 ;
for ( auto _ : state )
DoNotOptimize ( c = ( ++ a ) + ( ++ b ));
}
static void ll_add ( State & state ) {
long long a = std :: rand (), b = std :: rand (), c = 0 ;
for ( auto _ : state )
DoNotOptimize ( c = ( ++ a ) + ( ++ b ));
}
static void int_div ( State & state ) {
int a = std :: rand (), b = std :: rand (), c = 0 ;
for ( auto _ : state )
DoNotOptimize ( c = ( ++ a ) / ( ++ b ));
}
static void ll_div ( State & state ) {
long long a = std :: rand (), b = std :: rand (), c = 0 ;
for ( auto _ : state )
DoNotOptimize ( c = ( ++ a ) / ( ++ b ));
}
static void int_mod ( State & state ) {
int a = std :: rand (), b = std :: rand (), c = 0 ;
for ( auto _ : state )
DoNotOptimize ( c = ( ++ a ) % ( ++ b ));
}
static void ll_mod ( State & state ) {
long long a = std :: rand (), b = std :: rand (), c = 0 ;
for ( auto _ : state )
DoNotOptimize ( c = ( ++ a ) % ( ++ b ));
}
BENCHMARK ( int_add ) -> Threads ( 8 ) -> Iterations ( 1e9 );
BENCHMARK ( ll_add ) -> Threads ( 8 ) -> Iterations ( 1e9 );
BENCHMARK ( int_div ) -> Threads ( 8 ) -> Iterations ( 1e9 );
BENCHMARK ( ll_div ) -> Threads ( 8 ) -> Iterations ( 1e9 );
BENCHMARK ( int_mod ) -> Threads ( 8 ) -> Iterations ( 1e9 );
BENCHMARK ( ll_mod ) -> Threads ( 8 ) -> Iterations ( 1e9 );
BENCHMARK_MAIN ();
结果 1
2
3
4
5
6
7
8
9
10
---------------------------------------------------------------------
Benchmark Time CPU
---------------------------------------------------------------------
int_add / iterations : 1000000000 / threads : 8 0 . 209 ns 1 . 57 ns
ll_add / iterations : 1000000000 / threads : 8 0 . 225 ns 1 . 71 ns
int_div / iterations : 1000000000 / threads : 8 0 . 302 ns 2 . 29 ns
ll_div / iterations : 1000000000 / threads : 8 0 . 306 ns 2 . 38 ns
int_mod / iterations : 1000000000 / threads : 8 0 . 345 ns 2 . 18 ns
ll_mod / iterations : 1000000000 / threads : 8 0 . 350 ns 2 . 34 ns
经过多次测试,long long
类型的各种运算都比 int
慢一点。
StackOverflow 问答比较专业的一个解答。详见 performance - C++ int vs long long in 64 bit machine - Stack Overflow 。
这里引用相关问答:
1) If it is best practice to use long long in x64 for achieving maximum performance even for for 1-4 byte data?
No- and it will probably in fact make your performance worse. For example, if you use 64-bit integers where you could have gotten away with 32-bit integers then you have just doubled the amount of data that must be sent between the processor and memory and the memory is orders of magnitude slower. All of your caches and memory buses will crap out twice as fast.
结论可以不用 long long
就尽量不用。最好不要使用 #define int long long
这种粗暴手段。
致谢 :
碎碎念:真的有大半年没写过博客了,上次更新还是寒假呢哈哈哈。一整个学期都好忙啊,接下来就是初三了呢。
🙇