You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell程序汇编体积远超等效C代码的原因及编译优化疑问

为何GHC生成的Haskell程序汇编远长于等价C代码?

此前我提问《为何简单“乘2”Haskell程序二进制体积远大于C++?》被标记为重复问题,本次聚焦代码生成的汇编而非二进制,提出新疑问。

等价功能的C程序及汇编

C代码

int main(int argc, char * argv[]) {
    int r{0};
    int c{0};
    while (argv[1][c] != '\0') {
        r *= 10;
        r += argv[1][c++] - '0';
    }
    return r*2;
}

该程序功能为:接收1个数字命令行参数,转为int后返回其2倍作为退出码。

生成的汇编(仅21行)

main:                                   # @main
        mov     rcx, qword ptr [rsi + 8]
        movzx   edx, byte ptr [rcx]
        test    dl, dl
        je      .LBB0_1
        inc     rcx
        xor     eax, eax
.LBB0_3:                                # =>This Inner Loop Header: Depth=1
        movsx   edx, dl
        lea     eax, [rax + 4*rax]
        lea     eax, [rdx + 2*rax]
        add     eax, -48
        movzx   edx, byte ptr [rcx]
        inc     rcx
        test    dl, dl
        jne     .LBB0_3
        add     eax, eax
        ret
.LBB0_1:
        xor     eax, eax
        ret

等价功能的Haskell程序及汇编

Haskell代码

import Data.List (foldl')
import System.Environment (getArgs)
import System.Exit (exitWith, ExitCode (ExitFailure))
main :: IO Int
main = do
  [str] <- getArgs
  exitWith $ ExitFailure $ (*) 2 $ foldl' step 0 str
  where
    step i c = 10 * i + fromEnum c - fromEnum '0'

生成的汇编(共257行,是C的12倍多)

核心疑问

  • GHC编译器为何无法识别该main函数的简单逻辑,生成类似C的精简汇编?
  • 是遗漏了编译参数,还是这类小代码的优化未被GHC重视?
  • 或是受限于Haskell语言特性无法优化?
  • 是否调整代码写法能提升优化效果?

有评论指出这是因为包含运行时环境、thunk求值逻辑等,但该程序逻辑简单,为何仍需这些?为何小代码无法得到优化,必须达到代码量临界值?

Clang的优化对比

Clang能将计算置位数量的C代码:

int foo(int a) {
    int count = 0;
    while (a) {
        ++count;
        a &= a - 1;
    }
    return count;
}

直接优化为:

foo(int):                                # @foo(int)
        popcntl %edi, %eax
        retq

修改Haskell代码后的汇编变化

将代码中模式匹配改为head取参:

str <- getArgs
  exitWith $ ExitFailure $ (*) 2 $ foldl' step 0 $ head str

生成的汇编缩减至182行,但仍远长于C代码。我认为遍历惰性链表是Haskell的惯用写法,不应为优化放弃语言特性。

内容的提问来源于stack exchange,提问作者Enlico

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 03:43:35