电子产业一站式赋能平台

PCB联盟网

搜索
查看: 83|回复: 0
收起左侧

用 40 亿条 if 语句,只为判断一个数字是奇是偶?

[复制链接]

864

主题

864

帖子

8156

积分

高级会员

Rank: 5Rank: 5

积分
8156
发表于 2024-1-8 08:31:00 | 显示全部楼层 |阅读模式
点击上方“C语言与CPP编程”,选择“关注/置顶/星标公众号) |& f6 y$ E# X8 |% f
干货福利,第一时间送达!
2 L0 L+ i: T: r' R0 X7 ^& D3 w
2 I9 u6 M* c0 M. P! l" o# L( q6 U* W

ywrehzkgavv640106051732.png

ywrehzkgavv640106051732.png

* |1 H9 X1 m+ R% E转自:CSDN(ID:CSDNnews)
  Z( H- h# O/ Y/ ^
看到这个标题,相信大多数人的第一反应是:真的有人用 40 亿条 if 语句,只为判断一个数字是奇数还是偶数?
6 N0 C. [- F& G+ g& G& L的确有,这个开发者名为 Andreas Karlsson,他还把整个过程都整理成文了。
+ O' D' r  O7 w8 c! u% e% H

15l22ligikm640106051832.png

15l22ligikm640106051832.png
6 W, Q& A/ `1 e( l
或许由于这“40 亿条 if 语句”听起来实在震撼,Andreas Karlsson 分享的这篇文章在 Hacker News 上很快引起了极大的关注和讨论,而他在文中也直白表示:其实这个想法,最初源于一个充满恶评的短视频。+ h! L7 g) M1 m6 N  k" x: ]

aw5bpvdwhyl640106051932.png

aw5bpvdwhyl640106051932.png
/ Y7 C: a* u! b, s3 B* N7 K$ z
以下为译文:1 f% j' g0 u6 r4 `8 M

cni3nad0fs1640106052032.png

cni3nad0fs1640106052032.png
1 T0 z- [; d6 L, @
大于 11 的数字,没有输出结果- F8 Q5 u: B) O6 D6 N
我最近在火车上刷手机时,偶然发现了上面这个截图:“写了一个程序,来判断一个数字是偶数还是奇数。”点开评论区,果然是一连串的恶意评论,多数都在嘲笑这位新手程序员的稚嫩和无知,竟企图以这种方式解决计算机科学中的经典问题“取模运算”。
& s4 p3 |5 i+ u. C* ?可看过截图中的代码和网友评论后,我莫名生出了一些不同的想法:现在,AI 正在分分钟取代程序员、抢走他们的饭碗,并彻底改变了我们对代码的思考方式,或许我们应该更加开放地接受这个行业新生代的思想?5 k4 b* B- r2 L3 ~; t' T
其实仔细想来,上述代码是时间和空间的一种完美权衡:你在付出自己时间的同时,也换来了计算机的内存和时间——这难道不是一个神奇的算法吗?
: Y" }: Y, M. m, o; m于是,我开始探索这种只使用比较来判断一个数字是奇数还是偶数的想法,看看它在实际情况中的效果到底如何。由于我是一位高性能代码的忠实拥护者,因此我决定用 C 语言来实现这个想法。1 N2 K3 m" }+ @' R4 \' }
然后,我就开始编码了:
. ]2 w: Q0 n! c- K% c* o+ J/* Copyright 2023. All unauthorized distribution of this source code
& I& b9 C) t" {1 \% b0 x8 s: `5 P   will be persecuted to the fullest extent of the law*/: J" _% Y' j0 b! E8 n/ {0 X7 V
#include   ~' B" F" Y0 G+ s! i
#include + j: c& }4 g* R0 c* f& I( y+ V/ M
#include
; t: T6 q  P4 _' {- _int main(int argc, char* argv[])8 Q; D3 `: _- x% r3 S1 {
{
  K; J( _% ?( P+ d    uint8_t number = atoi(argv[1]); // No problems here
1 \' B. C4 t" V    if (number == 0)
! l; l8 [+ Y% {9 R7 j        printf("even9 O* l5 {, H& I  V9 ?( s0 y
");3 S# T, G( G3 K/ f5 v# P
    if (number == 1): j) u4 r3 e& z9 _7 `
        printf("odd% m( X' S3 M1 Y4 ^8 t( W+ ?+ ~! ]1 G
");2 d( [) c! J# H4 j" z- [. a1 \( @+ F
    if (number == 2), t. g4 t' c( o4 ?
        printf("even
8 [& R: ^6 U  u) a6 ]* b( X");0 I! [  @8 ~9 E# Y
    if (number == 3)
- j, z0 u* k* Y+ }8 f: x" H- Q        printf("odd
: F9 @3 x6 m7 Q" s2 m");
/ D6 @% W6 z, X0 \" G" g    if (number == 4)
; \, R) b' ?* s: R        printf("even* M8 ]$ Y1 W, z. W
");; U, _& G# d: e) w
    if (number == 5)9 u4 ~8 H; v6 r
        printf("odd9 b8 y$ c0 }2 S6 |6 E( T
");
7 ~" W: p6 J" g* C- e    if (number == 6)0 |- E' I5 b! K: @/ D) I8 t( l3 @
        printf("even$ x2 Q; S  j7 y9 L) S- R/ h# |  P
");
4 ]% I! U$ K5 P0 b    if (number == 7)
9 H5 t, m" D8 {4 l1 ~        printf("odd
, i; S, u/ l# Q; O8 k");" K6 U- d# p5 X5 Z. _: i+ n1 U
    if (number == 8)
' I" n9 V+ b% t+ c& e; T        printf("even; D$ \+ V; Q1 i( ]4 ]1 w0 ~6 g! P
");+ W0 w0 I+ G! |  B# \% o2 B
    if (number == 9); O" t8 B  P  A9 }. ?
        printf("odd
4 p3 w* u) m4 n0 c; C4 j3 O0 v");$ d  f' o' g. a1 j1 r) J
    if (number == 10)
. q; t% |( R+ ]1 x1 U7 }* A1 n        printf("even
. r- ?% k0 U# d. ^5 v+ q");
/ y2 M! r" s% |5 L}
! Q: L* Z: z5 ?7 @6 n接下来,我们要编译这段代码,使用 /Od 禁用优化,确保烦人的编译器不会干扰我们的算法。编译完成后,我们就可以对程序进行快速测试,看看结果如何:
) G2 K# H, f1 F5 ePS > cl.exe /Od program.c
/ N  L1 P3 B, H0 nPS > .\program.exe 0
$ Q- F$ Q" X7 ^even
& [* j# p+ |" M8 Y1 [4 u, k2 OPS > .\program.exe 4+ C) l4 j- J/ D7 b/ M- `+ b
even
1 T; k0 j6 @; e/ x( W, V! y! WPS > .\program.exe 3& c' }& `# ~# s& a, a- ~( z
odd# O: }1 ]' R0 J2 P* e
PS > .\program.exe 7
. Q: J3 t. m1 d$ m: M$ s/ _odd4 x# C- l. z/ \; O+ S; S; f
结果显示:0、4 是偶数,3、7 是奇数。这么看来,程序似乎运行得挺好,但在进一步测试后,我发现了一些问题:
; q, U) x: b- q2 q) [" ~PS > .\program.exe 50
. {( t* D7 P3 P1 H) S8 ~5 J% NPS > .\program.exe 11  g6 z4 @) |6 m
PS > .\program.exe 99( p$ }$ {! j9 y' c3 w( N

, c# r: P* v* a8 q- P4 o, ]大于 11 的数字没有输出,看来这个程序只对 11 以下的数字有效!回到原始代码中,可以发现问题出在最后一个 if 语句之后:我们需要更多的 if 语句!
/ {% l0 s- l# s6 G! v. ~

aveoj23prhh640106052132.png

aveoj23prhh640106052132.png
5 r) g3 a! B& }6 _
向 32 位(32-bit)数扩展9 E; D5 `4 K: r. }" U
这件事进行到这里,就需要我在时间和内存之间做出权衡了。考虑到我的寿命有限,我决定用另一种编程语言对 if 语句进行元编程。为了弥补这种“作弊”行为,我决定用“地球上速度最慢”的语言 Python。3 ^4 O  |" b( _& g! p: G: q9 {
print("/* Copyright 2023. All unauthorized distribution of this source code")% [$ _) A: H# a4 T6 v, ~8 G: n1 n
print("   will be persecuted to the fullest extent of the law*/")
9 v& ]7 d' t3 X( \' g& W
- R$ t# B( s0 l0 H9 Y% _2 ^print("#include ")! C; L# s2 E% ]3 o- @0 I
print("#include "): u5 V) H7 ~! a& Q8 c2 m3 g' E
print("#include "): q, Q3 }9 e: E. z
5 I2 r# F) s8 A+ R
print("int main(int argc, char* argv[])")2 ]$ P$ ^/ H. X
print("{")- h( l3 [3 W/ E) W* \: h
print("    uint8_t number = atoi(argv[1]); // No problems here")( V3 s/ o' `3 j" q' |

# a9 ~' o: M, e) mfor i in range(2**8):
. R0 A2 n  N3 V/ S    print("    if (number == "+str(i)+")")' t, P. n% J  O7 C9 @
    if i % 2 == 0:( ~9 a0 h- Y, u- x% H% G
        print("        printf(\"even\n\");")
+ A( R6 S# H" w$ x& _- k( ]7 L7 J+ Q    else:3 P0 _! R( [' I8 Q3 F
        print("        printf(\"odd\n\");")9 G3 o% U; S4 Y- r3 D8 m
print("}"); k! ]( f/ a  T9 w# I
好了!现在我们可以生成一个程序,解决所有 8 位(8-bit)整数的奇偶问题!6 V7 ]7 k. M& u% |
PS > python programmer.py > program.c' N' @. a" R( m, o* c5 y
PS > cl.exe /Od program.c
* g6 }- i1 D1 W# U+ \- SPS > .\program.exe 99# o+ B3 n2 Z. q4 n; g
odd
+ X/ Y& J9 H, v1 W& I# E- nPS > .\program.exe 50
  ]8 b6 M( }% c: d7 E- @: r/ xeven/ e5 t$ n* U/ y3 v3 y5 m6 I1 d; `
PS > .\program.exe 240  \! I6 G% ]  V) O6 y
even% j" g: }/ }6 a9 o( B, B; B
PS > .\program.exe 241+ W- _0 T$ e0 q$ c2 S5 n0 M
odd# N0 y/ W! n5 y2 v" r7 Y! {; h& _9 A
看看,这个效果简直完美!现在,让我们把它放大到 16 位(16-bit)!* e. D1 Y5 W: G' Z
print("    uint16_t number = atoi(argv[1]); // No problems here")
3 o% t$ k. \& R! a
+ B4 i) d. q" t6 j, `  Mfor i in range(2**16):0 }+ g8 w* j3 W$ c, }2 D

+ q4 g- }9 k9 Z7 O# o8 a% M这样就得到了一个约 13 万行、超长且漂亮的 c 文件。回顾了一下我多年工作所做的一些代码库,这其实不算什么。话不多说,开始编译!
8 D: {9 J. Y' S+ ^PS > python programmer.py > program.c. b+ q2 ^. y; H6 f" z  y+ g9 ^
PS > cl.exe /Od program.c
' _, H% `# Q1 Y' e; `PS > .\program.exe 21000  L; H! ~. E- {& w: P& Y9 l. Z
even
" h6 K6 e; Z: S' @9 ^PS > .\program.exe 3475
' u6 h! u( O* f' w& k1 qodd" h# q8 g4 y2 O. P  G
PS > .\program.exe 3   
% M5 y/ z- b% T. r* j1 B9 [odd
- w# r0 _& s# P: W5 f! i) c! l, mPS > .\program.exe 650010 \' O9 e* ^2 h6 ^% j! b. e
odd' A# I7 r* h7 j5 |
PS > .\program.exe 65532
; F, ?2 X" S9 x# k- D$ R" |even
4 d  s2 @( a0 q5 q' q太棒了,我们的算法似乎能够处理大量数据!可执行文件大约只有 2 MB,但这与我拥有高达 31.8 GB 内存的强大游戏设备相比,简直不值一提。
' d5 ]" a2 T0 S& B5 h但众所周知,32 位(32-bit)才是计算机领域的终极目标,也是我们解决所有实际工程和科学问题所需的最终位宽。毕竟,在 IPv4 因所谓的 "地址耗尽 "而被认为过时 60 年后,它如今仍然很强大。所以,让我们来看看最终的规模:32 位的数字是 16 位的 65536 倍,这会有什么问题吗?
$ m/ Q7 T* U/ s( Q- v/ p$ v9 l6 Rprint("    uint32_t number = atoi(argv[1]); // No problems here")" t9 B7 g" s1 v! E

2 T) U* K% W( S) l- e6 z2 ^for i in range(2**32):; T3 i" X7 a" \) }' M2 v; O
于是,我让强大的 Python 开始它的工作。48 小时后,我喝了一杯咖啡,然后回来检查程序,就得到了一个美丽的 c 文件,大小接近 330 GB!我几乎可以肯定,这是历史上最大的 c 文件之一。当我输入下一条命令时,我的手指都在颤抖,我猜 MSVC 肯定从未遇到如此强大的源代码。; ~8 V, G! L1 C# [- \8 P
在我那台可怜而强大的电脑页面文件中遭受半小时的折磨后,输出如下:
7 j) ]" F% a5 S$ |PS > cl /Od program.c
. A6 c& v, f. ~( LMicrosoft (R) C/C++ Optimizing Compiler Version 19.32.31329 for x64
; [( s: A, X2 Z; J) L6 wCopyright (C) Microsoft Corporation.  All rights reserved.; G$ c4 m/ M3 l. f

/ y4 s* W7 `: S! Yprogram.c1 ?* \4 m" L* G3 G( L( {3 m0 }  k% U
program.c(134397076): warning C4049: compiler limit: terminating line number emission' u; j9 L, }8 h5 E1 J' `) f6 |3 d- y
program.c(134397076): note: Compiler limit for line number is 16777215
2 Y$ H& E7 }# V* G) P, J9 Dprogram.c(41133672): fatal error C1060: compiler is out of heap space7 c. T9 ]$ N  R2 ~8 V: S# A
太令人失望了!不仅编译器让我失望,在研究 Windows 可移植可执行文件格式(.exe)的限制时,我发现它无法处理超过 4GB 的文件!由于需要将 40 多亿次比较语句编码到可执行文件中,这对于实现我们的算法是一个主要障碍。即使每次比较时使用的字节数少于一个,对我来说工作量也太大了。* [  l* [4 T% r" y. W9 _
不过,糟糕的编译器和文件格式不应该阻止我们实现梦想。毕竟,编译器所做的只是将一些花哨的机器代码写入文件,而文件格式只是一些结构,告诉操作系统如何将二进制代码放入内存——其实,我们自己就能做到。
8 \1 O4 ?; C: N+ D5 D# p: ^

sxosmui3bor640106052232.png

sxosmui3bor640106052232.png
. Y4 V- R  l. G  \, U7 N
解决最后一个问题,程序性能很不错" O. ]2 l# \' J: k
让我们先用 x86-64 汇编语言编写一个 IsEven 函数,因为这是我 Intel 处理器驱动的本地语言,它看起来是这样的:
# {1 z1 j: c% o+ R: E! x; Argument is stored in ECX, return value in EAX" O8 ?: I/ A$ j7 q; u" R: R4 P
XOR EAX, EAX ; Set eax to zero (return value for odd number)
# D; I: j. _5 z$ A6 SCMP ECX, 0h ; Compare arg to 0
& E" t( V% Y  d' U) h2 b& f9 y8 XJNE 3h ; Skip next two instructions if it wasn't equal( |6 q$ o8 @0 R( M
INC EAX ; It was even, set even return value (1)
1 W  I2 U# a% t3 f9 H8 LRET ; Return+ t, U( L/ O; T
CMP ECX, 1h ; Compare arg to 1/ S/ c! D& o( F* T/ _
JNE 2 ; Skip next instruction if not equal
# [: m4 r; x; o- j7 r6 ERET ; Odd return value already in EAX, just RET4 X3 m8 B! {% s! e/ L4 Z
; add the next 2...2^32-1 comparisons here0 C0 k0 x, Q! S3 B
RET ; Fallback return
6 a9 E# r4 D$ L这并不是真正正确的汇编代码,但这不重要,因为我们要手动将其编译成机器代码。
% `5 \+ R5 N% g* I* n你问我是怎么做到的?我上网查阅了x86(-64) 体系结构手册,还利用我早年编写仿真器和黑客经验,找出了每条指令的正确操作码和格式……开个玩笑,这是不可能的。实际上,我是直接问 ChatGPT 每条指令的正确操作码是什么,幸运的是,它也没有产生 x86-64 的任何新扩展。0 u1 t% @9 q+ I. \# ]
所以现在我们只需编写一个“编译器”来输出这段代码。请注意,我们将直接使用从 AI 获取的指令操作码,下面是用 Python 编写的代码:
$ i* r$ l- R2 |import struct+ k* w6 o9 n  A2 p+ h
with open('isEven.bin', 'wb') as file:4 M6 ?+ W  J3 \% N0 z
    file.write(b"1à")                     # XOR EAX, EAX
" J- s# Y1 O0 @# R
: w5 H1 M, Y) [    for i in range(2**32):1 k, _" A4 W3 w) X; @0 d6 n( O
        ib = struct.pack("[I], i)               # Encode i as 32 bit little endian integer' N) @, r3 U# q2 n( A4 O# x

- q$ l% \0 g' y8 Z        file.write(b"?ù" + ib)            # CMP ECX, i; ^+ O" |# a3 F! b7 t: ^3 a/ e
2 j( w8 O0 n' b! V) D
        if i%2 == 0:
3 s- u" a* R0 ~4 q/ Z6 l            file.write(b"u")             # JNE +3# e6 S0 ]# D: w
            file.write(b"?à")             # INC EAX* S5 \, s2 Q5 `* J9 E
            file.write(b"?")                 # RET( I* k2 N4 q6 Z. S, S
        else:; Y2 o+ `4 x2 U4 y
            file.write(b"u")             # JNE +11 C& X6 B% W8 M5 }5 R( V8 e
            file.write(b"?")                 # RET
4 a7 W# ~3 i6 T: m* O% H% F4 _+ L: n1 m) P& C# m
    file.write(b"?")                         # Fallback RET- |% X  |3 ~* e, A! G3 ]4 R7 C
虽然我们在一定程度上偏离了开头 TikTok 帖子的最初构想,但本质并没有改变:我们创建了一个非常长的 if 语句列表,用于确定某个数字是奇数还是偶数,并忽略了任何有助于简化问题的算术运算。
# V. E* z4 k' w  F3 ]运行这个程序后,我们就得到了一个 40GB 的文件,其中包含了确定 32 位数字是偶数还是奇数所需的全部 42 亿次比较!现在,我们只需编写能够加载和使用这些指令的主程序。为了提高性能(这一点非常重要),我决定将文件映射到地址空间,而非一次性读取全部文件。这样,我们就可以假装整个文件已经在内存中,让可怜的操作系统来处理将一个 40GB 的 Blob 装入虚拟内存的问题。用 READ 和 EXECUTE 权限映射文件后,我们就可以使用函数指针调用代码了,代码如下:
3 |5 ]( e( T& y2 f: f' B+ F. p5 |+ G: Z#include % l9 H8 n( O$ K
#include 2 R% s0 ~* g6 N: p) l/ c- }
#include & A1 ]3 W; h+ ~$ D

  k0 y  j% J: a: T# ]  v1 y& Fint main(int argc, char* argv[])
2 G6 b9 |1 G5 B8 K* R! _{
6 u8 {8 p* p9 i7 i) i5 }+ W( ]" o    uint32_t number = atoi(argv[1]); // No problems here
( h" `5 M: L* x1 y- u5 Q5 U, Q2 \6 P& L5 X$ u" w
    // Open code file
( H5 w$ H3 C1 Y- i9 p4 r0 A    HANDLE binFile = CreateFileA(
0 a7 h: G5 f. s+ `2 v                        "isEven.bin",2 r8 t2 M) l# V3 n
                        GENERIC_READ | GENERIC_EXECUTE, FILE_SHARE_READ,
5 s! V* M) t: A9 ~5 ^+ G                        NULL,9 n4 w2 T9 {  ]/ F6 J# ^/ p* C  E: S
                        OPEN_EXISTING,
6 S- m, k$ k4 F1 o                        FILE_ATTRIBUTE_NORMAL,
; m0 P: R( S) v9 s7 ]6 A9 N9 }" W1 M6 _                        NULL);9 u/ y8 {# D# |
    // Get 64 bit size of file
& \5 u: e  `* L$ |' B9 `' M8 x$ D    LARGE_INTEGER codeSize;: S$ a4 X1 Y: A# t0 C
    GetFileSizeEx(binFile, &codeSize);
& A, i, c2 g' v5 S& d% s7 V0 E6 f5 X% U% R
    // Create memory map of the file' S! i8 n8 a" J/ y+ R
    HANDLE mapping = CreateFileMapping(% m: |" v5 X: q' b# h- o6 X
                        binFile,0 p* d. j( K% G: d6 E# q3 r2 N
                        NULL,% i5 k' n( S# y- y
                        PAGE_EXECUTE_READ,6 ~4 ?8 p, M2 }& L
                        0,  v" k$ H  L8 [$ A* e
                        0,# l* ^6 y" {7 O. C
                        NULL);7 B: s: W6 m" x
+ I; v+ E9 }6 |8 E+ m" I3 l
    // Get a pointer to the code& }, m$ W- c, k9 a! J" r; H) x
    LPVOID code = MapViewOfFile() v  b% }: b. h( i7 G
                    mapping,FILE_MAP_EXECUTE | FILE_MAP_READ,1 R, a2 C' W6 M% ]+ i, T0 J2 y% {
                    0,1 Z* M( z/ x. y! f, P  E& ^" m
                    0,: W2 V& l1 v0 ^0 t/ g1 Z
                    codeSize.QuadPart);
4 w! F4 R5 ^8 |: I) l( r6 ~, ?4 K# a, d. Y  m8 U$ c5 F9 S
    // Create a function that points to the code8 p$ n/ E. u: l5 T. l! K
    int (*isEven)(int) = (int(*)(int))code;
5 M+ O6 d2 [" `" k5 S  p. K  q1 N( O
    if (isEven(number))' N& N. l" b9 i) u5 }0 r
        printf("even
7 d! b0 A4 ~, Q8 B5 P  w");
: }5 l; e5 Z4 u6 }: Y) D2 I    else' m( N, v" Z+ K1 J* r2 M
        printf("odd
; ]) f7 Q1 l, ?- j- t$ l/ G");3 Z; c' I1 \2 s: @$ x/ w0 u
. Z5 X% v" h% v
    CloseHandle(binFile);  i. R4 `" n1 ^+ {1 r
}
) e! x/ D* Z: i+ C就是这样!现在我们已经具备了判断任何 32 位(32-bit)数字是奇是偶的所有功能,让我们试一试:) q9 z# p+ m$ U# \
PS >.\program.exe 300
& E$ L  L1 ~" p5 d8 D% heven
: h6 l% }% a, G' H4 R3 sPS >.\program.exe 0( i6 ]: L1 m' m3 D7 K* K* h
even
& O( {7 p1 u5 O2 d  FPS >.\program.exe 1000000
% ?, J6 H+ B. e$ m: }7 Keven: U: g, b% v- A* t% N
PS >.\program.exe 100000007) _; g, c- ~5 X  l5 U4 r, I
odd
5 i, ~+ K( b4 B- M, l% \+ FPS >.\program.exe 4000000002 J* p( m! e( _$ |! b; b4 ?  M
even
# P: |. h, J# p+ V. w5 c( K% ?PS >.\program.exe 400000001
" D9 O* }1 ]( k0 j/ {odd7 `3 Z  e! ]$ ?/ c4 J* g
PS >.\program.exe 400000006% S6 X3 L. e: @; y7 [! y+ [8 A
even; s( l* b' A9 D0 f! M( m
PS >.\program.exe 4200000000
2 o+ n% s3 f  |9 U/ Codd 差不多了!似乎算法在符号性方面有问题,任何超过 2^31 的值似乎都会给出随机结果。那么,让我们来修复最后一个错误:原来 atoi 不能处理无符号性,所以它无法解析大数字。用 strtoul 代替它就能解决所有问题。
- G0 D) G1 b" }1 P# T9 ~5 huint32_t number = strtoul(argv[1], NULL, 10);// No problems here
( D+ |) K% p3 P$ A. bPS >.\program.exe 4200000000
1 s3 q( ?" i+ [1 oeven
' h4 x0 X7 ^; j$ x, N' YPS >.\program.exe 42000000018 c* b, ^" J: K; o( z' t7 v
odd顺便提一句,这个程序的性能很不错。对于小数字,结果能即时返回,而对于接近 2^32 极限的大数字,结果仍能在大约 10 秒内返回。考虑到计算机必须从磁盘读取 40GB 的数据,将其映射到物理内存,然后让 CPU 在没有缓存的情况下对其进行处理,老实说这个速度已经相当令人惊叹了。作为参考,我电脑的配置为 Core i5 12600K,32GB 内存,文件存储在 M.2 SSD 硬盘上。在计算过程中,我看到 SSD 硬盘的峰值读取速度约为 800 MB/s。
% _. L, b( [* A. x至此,互联网再次被证明是错误的:你不仅可以按照 TikTok 帖子的方式编写一个功能齐全、性能良好的程序,而且还非常有趣。$ T8 `$ X0 p1 R

153x1nda3eq640106052332.png

153x1nda3eq640106052332.png

4 n; }2 ?" e4 m网友:没必要,一个简单的 for 循环就能解决
' u! n8 H: V8 A" {8 ?4 y不过 Andreas Karlsson 的分享,并没有得到部分开发者的认可,甚至认为他有些“哗众取宠”:" g8 N/ V, d7 Q$ s7 l
“在我看来,这几乎是过度设计。为什么要费尽心思生成代码?只需一个简单的‘for 循环’就能解决。”
, s( `# ?8 M, C
func isOdd(n int) bool {
+ F' Z5 W" e7 o* {5 _3 l3 [4 E    var odd bool
3 e+ c4 d# o* {- M    for i := 0; i return odd
* n/ x& L2 U' U1 h  }8 @: J; D; H. v* X/ {. ?
4 x: W1 X1 J! j7 k
“真正高质量的运行应始终使用递归。”& C! ]& p2 y3 L4 @) m7 l
func isOdd(n int) bool {
% B2 }- ~2 i( d! Q1 D$ a1 K    switch {! [9 N0 G( A8 g7 N' }7 g' r( Q, Y
    case n == 0:
1 l; n% R: c: }/ l$ ~      return false  V) H# W* U) h6 }3 c0 _; }  F
    case n > 0:
. d; z( g+ K- E9 I1 G  `      return !isOdd(n-1)% I  b  [% e$ u0 {0 R9 ?% p+ z
    default:: N" e9 v& ?9 r; i% T" \8 o$ \0 z
      return !isOdd(n+1)
" D: p1 L2 F$ g    }
) i. z1 {7 `6 W3 q4 f  }
8 E3 `) l' p; X6 A2 \' [
还有人指出:“我完全听不懂这个笑话。我们从中学到了什么?exe 文件不能超过4GB?一个2^32 if 的程序大约是300GB?这看起来并不疯狂,只是毫无意义。”
! l# U# t) O! u9 V2 ~/ k! K7 d' m对此,有人反驳道:“可笑的是,他真的做到了。几十年来,人们一直在拿它开玩笑,但这个人是认真的。由于代码多得太极端,没有编译器可以处理,甚至没有任何已知的汇编程序,因此他必须生成自己的机器码二进制文件才能运行。结果最后,他居然还真的成功了。”
1 T: x, j2 u" N! ~8 w0 z+ _  \# w参考链接:% C0 U5 n1 N' ~
https://andreasjhkarlsson.github.io/jekyll/update/2023/12/27/4-billion-if-statements.html
0 ^2 N) V( C2 B) N- Khttps://news.ycombinator.com/item?id=38790597, W3 B+ b; k7 Y- x/ _5 g7 I
使用函数指针可以帮助我们编写更加灵活和通用的代码,并提高代码的可重用性和可扩展性。3 c+ T' f" N& \( ]9 G3 C
?版权声明:本文来源网络,免费传达知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除。——EOF——你好,我是飞宇,本硕均于某中流985 CS就读,先后于百度搜索以及字节跳动电商等部门担任Linux C/C++后端研发工程师。5 K  @1 y6 a* V! x5 r
最近跟朋友一起开发了一个新的网站:编程资源网,已经收录了不少资源(附赠下载地址),如果屏幕前的靓仔/女想要学习编程找不到合适资源的话,不妨来我们的网站看看,欢迎扫码下方二维码白嫖~" v8 t6 U* n: c1 ~0 D- P) e

- e+ C1 }  f$ e$ T; g; Z

5540en5towj640106052434.gif

5540en5towj640106052434.gif
( [3 D& N  c. Z. r6 j7 h6 D5 _# i
, \: O0 Z4 B5 r) M2 w( `: h6 a
同时,我也是知乎博主@韩飞宇,日常分享C/C++、计算机学习经验、工作体会,欢迎点击此处查看我以前的学习笔记&经验&分享的资源。
6 i8 c) P3 @) `& J. C: j, F我组建了一些社群一起交流,群里有大牛也有小白,如果你有意可以一起进群交流。, `4 S2 ]- N/ a6 ~* [1 u

mhzl0i1wv3o640106052534.png

mhzl0i1wv3o640106052534.png

4 q* |% V/ M  r/ R5 t+ v欢迎你添加我的微信,我拉你进技术交流群。此外,我也会经常在微信上分享一些计算机学习经验以及工作体验,还有一些内推机会。
1 e& A- N" B3 n$ i/ F9 }
6 y; W5 B2 d  D1 M- C

04h1jnkv4ir640106052634.png

04h1jnkv4ir640106052634.png

9 _1 w* Q/ L0 I加个微信,打开另一扇窗
' I( R7 w, g2 k

afrslusxa5q640106052734.gif

afrslusxa5q640106052734.gif
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


联系客服 关注微信 下载APP 返回顶部 返回列表