HackerURLs

一次又一次被重新发现的经典。

同一个链接,相隔一年以上,一次又一次被人重新发现、再次冲上 Hacker News 首页。能经受住这种时间检验的,大多是值得一读再读的文章。每篇附中文标题,讨论最热的那些再加上中文导读和高赞评论翻译。

从名人堂开始
  • 4,700+篇经过时间检验的经典

Hall of fame

名人堂

在经典库里看全部精选

上首页次数最多、而且有中文导读的 30 篇。时间轴上每个黑点是一次上首页,空心点是一次没冲上去的投稿。

  1. 正在载入经典…

Archive

经典库

按第一次上首页的年份分布,点柱子筛选。

排序

    About

    这些经典是怎么挑出来的

    1. 01

      合并同一个链接

      读取 Hacker News 自 2006 年以来的全部链接投稿,把 http/https、www、跟踪参数等写法不同的同一篇文章合并成一条。

    2. 02

      只留经得起时间的

      同一链接至少两次拿到 50 分以上(约等于上首页),而且两次相隔一年以上;再由 AI 剔除状态页、产品首页和新闻事件。

    3. 03

      写导读、译评论

      上首页次数最多的 2,000 篇配上中文导读、"为什么经久不衰",并精选翻译 HN 高赞评论。导读由 AI 生成,可能有误。

    编程与软件工程lifthrasiir.github.io

    为什么 Rust 可执行文件这么大?

    Why is a Rust executable large?

    2次上首页
    3年跨度
    543累计得分
    241条评论

    2016 — 2019,它一次次回到首页

    黑点是上首页(≥ 50 分)的那次投稿,空心点是没冲上去的投稿,点越大分数越高。

    导读

    这篇文章以 Rust 的 Hello World 等可执行文件为例,拆解它为什么比同等 C 程序大:静态链接的标准库/运行时、调试信息,以及当时默认使用的 jemalloc 等都会计入体积。作者还演示了 strip、动态链接和直接调用系统接口等减小二进制的方法,并比较不同构建选项的取舍。

    为什么经久不衰:因为它把“二进制为什么大”还原为链接方式、调试信息和运行时的具体取舍,给出可操作的优化路径,所以多年后仍是理解 Rust 构建体积的经典入口。

    关键词 Rust二进制大小链接优化LTO

    HN 评论精选

    区分调试信息与符号表,建议用 strip --strip-debug,并配合 -ffunction-sections/-fdata-sections 使用 --gc-sections。

    我一直在做一个工具,想回答更一般的问题:为什么我的二进制文件(C、C++、Rust 等写的)这么大?我们用 CPU profiler 解释程序为什么慢,我的工具则像 size profiler:程序为什么大?对文章有几点直接评论:不建议完全 strip,改用 strip --strip-debug(或者干脆不用 -g 编译);调试信息和符号表是两回事,调试信息大得多(4 倍以上)且远非必需,去掉调试信息但保留符号表仍能获得 backtrace。另外,我不认为 -Wl,--gc-sections 有效,除非同时用 -ffunction-sections 和/或 -fdata-sections 编译,而文中的 C/C++ 示例没有这样做。现在如果在乎 C/C++ 二进制大小,大概应该加上这些选项,可惜它们不是默认。

    haberman查看英文原文

    I've been playing around with a tool to answer the more generic question: why is my binary (written in C, C++, Rust, etc) so large? We use CPU profilers to tell us why our programs are slow. My tool is intended to be a size profiler: why is my program big? It turns out there are some really interesting analyses and visualizations you can perform to answer this question. A few direct comments on the article: - I do not recommend stripping your binaries completely! Use "strip --strip-debug" instead (or just don't compile with -g). You should realize that debug information and the symbol table are two separate things. The debug information is much larger (4x or more) and much less essential. If you strip debug information but keep the symbol table, you can still get backtraces. - I don't believe -Wl,--gc-sections has any effect unless you also compile with -ffunction-sections and/or -fdata-sections, which these examples for C/C++ do not. If you care about binary size in C or C++ you should probably be compiling with -ffunction-sections/-fdata-sections/-Wl,--gc-sections these days. Sadly, these are not the default.

    静态链接的 Rust 在系统层面会放大体积,而动态链接又受 Rust 无稳定 ABI 和频繁升级制约。

    谨慎地问:这个问题到底成立吗?我们有数百 GB 甚至 TB 存储,人们也该有像样的 ISP,二进制大小不该担心,对吧?$ find /usr/bin -type f | wc -l 得到 2254 个文件,du -sh /usr/bin 是 445M。如果这些程序都用 Rust 写并静态编译,假设每个只差 600K,/usr/bin 就会变成 1.3G(增大 300%)。但现实中这些程序动态链接 /usr/lib 里的许多库,所以差异会更大,因为库会在所有程序间重复。当然 Rust 也能动态链接,但会碰到另一个问题:没有稳定 ABI(至少当时),而且每 6 周升级 Rust 意味着全部重编译。

    glandium查看英文原文

    > Just to be cautious: Is it a valid question to ask after all? We have hundreds of gigabytes of storage, if not some terabytes, and people should be using decent ISPs nowadays, so the binary size should not be a concern, right? $ find /usr/bin -type f | wc -l 2254 $ du -sh /usr/bin 445M /usr/bin If all these programs were written in Rust and statically compiled, assuming only a 600K difference by binary, that would make my /usr/bin 1.3G (or 300%) larger. But in reality all those programs are dynamically linked against many libraries in /usr/lib, so the difference would be even bigger, with libraries duplicated between all those programs. Sure, you can dynamically link with Rust too, but then, you hit the other problem that there is no stable ABI (yet?), and that upgrading Rust (every 6 weeks) means recompiling everything.

    把所有代码(含汇编)放进 Rust 源文件并启用 LTO,可把固件从约 1MB 降到约 70KB,Rust 大小优化很依赖 LTO。

    对写嵌入式固件的人,我最近一个演讲(关于任天堂 64 Rust 开发套件)的一个子要点是:要避免 C/C++ 中常见模式——大部分代码在静态库里,再把可执行文件作为第二步构建。相反,你应把所有代码包括汇编都放在 Rust 源文件里,以便尽可能无痛地生成经过 LTO 的二进制。我的二进制大小从约 1MB 降到约 70KB。如果你在乎二进制大小,Rust 真的很依赖 LTO。

    monocasa查看英文原文

    For those writing embedded firmware, one of the subpoints of a talk I did recently (about a rust dev kit for the Nintendo 64) was that you want to avoid a standard model where in C and C++ you might have most of your code in a static library and build the executable as a second step. Instead you really want all of your code including your asm in rust source files so it's as painless as possible to generate an LTOed binary. I had binary sizes go from ~1MB to about ~70KB. Rust really depends on LTO if you care about binary size.

    2019 年实测 C/Rust Hello World 都变大,Rust 增长主要来自调试信息,strip 后约 187K,与文章去掉 jemalloc 后的数字接近。

    我机器上两个可执行文件自 2016 年以来都变大了。Linux 上不优化不 strip:C Hello World 19K;Rust Hello World 1.6M(!)。C 的增长可归因于 ld 的变化:自 ld 2.30 起安全加固默认把只读数据和可执行数据放到不同段。我不明白为什么不该产生三个段(R、RE、RW),但我这里得到四个(R、RE、R、RW)。(有人知道为什么四个吗?)传 -znoseparate-code 关闭后 C 回到文章里的 8K(对 Rust 没影响)。Rust 的增长似乎主要在 debug info。strip 后我得到 187K,和文章去掉 jemalloc(现在默认不再包含)并 strip 后的 121K 相近。有人知道 Rust 从 2016 到 2019 为什么长了这么多吗?

    edflsafoiewq查看英文原文

    Both executables have grown on my machine since 2016. On Linux, no optimization or stripping * C Hello World - 19K * Rust Hello World - 1.6M (!) The C gain is attributable to a change to ld: it puts read-only data and executable data in separate segments by default as a security hardening measure since ld 2.30. I don't see why this shouldn't produce three segments (R, RE, RW), but here I get four (R, RE, R, RW). (Anyone know why four?) If I pass -znoseparate-code to disable this the C goes back to the 8K shown in the article. (No effect on the Rust). The Rust gain appears to be mostly in debug info. Stripped I get 187K, which is similar to 121K the article gives after stripping and removing jemalloc (which isn't in by default anymore). Does anyone know why Rust has grown so much from 2016 to 2019?

    历次讨论

    同类还值得读

    1. 开源应用架构

      The Architecture of Open Source Applications

      《开源软件架构》(AOSA)是一本在线免费书,邀请知名开源项目的作者亲自剖析其内部设计,涵盖 SQLAlchemy、LLVM、Audacity、Apache、Bash 等系统。

      编程与软件工程上首页 9 次 · 2011–2024aosabook.org编辑精选
    2. 编程语言简史:简短、不完整且多半错误

      A Brief, Incomplete, and Mostly Wrong History of Programming Languages

      一篇以戏谑、故意不准确的方式回顾编程语言史的博客文章,用夸张轶事和讽刺定义串起 Lisp、C、C++、Java、JavaScript、PHP 等语言。

      编程与软件工程上首页 8 次 · 2009–2021james-iry.blogspot.com
    3. SQLite 是如何测试的

      How SQLite is tested

      SQLite 官方文档页,系统介绍 SQLite 的测试体系:多种测试方法(TCL 测试、模糊测试、回归测试、静态分析等)和海量测试用例,展示了这个小型开源项目如何靠极致测试获得…

      编程与软件工程上首页 8 次 · 2009–2025sqlite.org编辑精选
    4. 高级编程语言(2009)

      Advanced programming languages (2009)

      Matt Might 的经典文章,按用途推荐“高级编程语言”:如果追求就业就选主流语言,如果追求表达力、学术研究或创业,则推荐 Haskell、OCaml、Scala 等函数式语…

      编程与软件工程上首页 8 次 · 2009–2022matt.might.net
    5. 我的 Forth 与栈机器经历

      Yosefk - My history with Forth & stack machines

      作者以亲身经历回顾了使用 Forth 语言和栈式机器的历程:既赞叹其简洁优雅、代码量小、可自举的优点,也坦率指出栈操作在实际编程中的痛苦,以及 Forth 社区文化中的问题。

      编程与软件工程上首页 8 次 · 2010–2024yosefk.com编辑精选

    打赏支持

    打赏二维码

    觉得有用,请作者喝杯咖啡。

    WeChat

    关注向阳乔木

    微信公众号「向阳乔木推荐看」

    微信公众号「向阳乔木推荐看」二维码

    微信扫一扫;在微信里打开本页时,长按二维码识别。