小巧、快速、可靠。
请选择其中的三个。
为什么 SQLite 用 C 语言编写

1. C 语言是最佳选择

注意:本文的 2.0 和 3.0 节是根据对 Hacker NewsReddit 的评论添加的。

自 2000 年 5 月 29 日诞生以来,SQLite 一直使用通用 C 语言实现。C 语言一直是,并且仍然是实现像 SQLite 这样的软件库的最佳语言。目前没有计划将 SQLite 重写为其他任何编程语言。

C 语言是实现 SQLite 的最佳语言的原因包括

1.1. 性能

像 SQLite 这样被密集使用的底层库需要速度快。(SQLite 确实很快,例如,请参见 内部 BLOB 与外部 BLOB比文件系统快 35%。)

C 语言非常适合编写快速代码。C 语言有时被描述为“可移植的汇编语言”。它使开发人员能够尽可能接近底层硬件进行编码,同时仍然保持跨平台的可移植性。

其他编程语言有时声称“与 C 语言一样快”。但没有其他语言声称在通用编程方面比 C 语言更快,因为确实没有。

1.2. 兼容性

几乎所有系统都能够调用用 C 语言编写的库。其他实现语言则并非如此。

因此,例如,用 Java 编写的 Android 应用程序能够调用 SQLite(通过适配器)。也许对 Android 来说,如果 SQLite 用 Java 编写会更方便,因为这将使接口更简单。但是,在 iPhone 上,应用程序是用 Objective-C 或 Swift 编写的,它们都没有调用用 Java 编写的库的能力。因此,如果 SQLite 用 Java 编写,它将无法在 iPhone 上使用。

1.3. 低依赖性

用 C 语言编写的库没有巨大的运行时依赖性。在最低配置下,SQLite 只需要标准 C 库中的以下例程

  • memcmp()
  • memcpy()
  • memmove()
  • memset()
   
  • strcmp()
  • strlen()
  • strncmp()

在一个更完整的构建中,SQLite 还使用 malloc() 和 free() 等库例程,以及用于打开、读取、写入和关闭文件的操作系统接口。但即使这样,依赖项的数量仍然非常少。相比之下,其他“现代”语言通常需要加载有数千个接口的多兆字节运行时。

1.4. 稳定性

C 语言古老而乏味。它是一种众所周知且易于理解的语言。这正是开发像 SQLite 这样的模块时所期望的。在没有实现语言随着每次实现语言规范的更新而发生变化的情况下,编写一个小型、快速且可靠的数据库引擎已经足够困难了。

2. 为什么 SQLite 不用面向对象语言编写?

有些程序员无法想象用一种不是“面向对象”的语言来开发像 SQLite 这样的复杂系统。那么为什么 SQLite 不用 C++ 或 Java 编写呢?

  1. 用 C++ 或 Java 编写的库通常只能被用同一种语言编写的应用程序使用。让用 Haskell 或 Java 编写的应用程序调用用 C++ 编写的库很困难。另一方面,用 C 语言编写的库可以从任何编程语言调用。

  2. 面向对象是一种设计模式,而不是编程语言。你可以在任何你想要的语言中进行面向对象编程,包括汇编语言。有些语言(例如:C++ 或 Java)使面向对象更容易。但你仍然可以在像 C 语言这样的语言中进行面向对象编程。

  3. 面向对象并不是唯一有效的設計模式。许多程序员都被教导只用对象的思维方式思考。公平地说,对象通常是分解问题的很好方法。但对象不是唯一的办法,而且并不总是分解问题的最佳方法。有时,传统的程序代码比面向对象代码更容易编写、更容易维护和理解,而且速度更快。

  4. 当 SQLite 最初开发时,Java 是一种年轻且不成熟的语言。C++ 比较古老,但它正在经历如此剧烈的成长阵痛,以至于很难找到两个使用相同方式工作的 C++ 编译器。因此,当 SQLite 最初开发时,C 语言无疑是更好的选择。现在的这种情况没有那么严峻,但目前重写 SQLite 几乎没有益处。

3. 为什么 SQLite 不用“安全”语言编写?

近年来,人们对像 Rust 或 Go 这样的“安全”编程语言产生了浓厚的兴趣,在这些语言中,不可能,或者至少很难,出现常见的编程错误,如内存泄漏或数组越界访问。因此,人们经常会问,为什么 SQLite 不用“安全”语言编写。

  1. 在 SQLite 诞生的前十年,所有这些安全编程语言都不存在。SQLite 可以用 Go 或 Rust 重写,但这样做可能会引入比修复的错误更多,并且似乎也有可能导致代码变慢。

  2. 安全语言插入额外的机器分支来执行诸如验证数组访问是否在范围内之类的操作。在正确的代码中,这些分支永远不会被执行。这意味着机器代码不能被 100% 分支测试,这是 SQLite 质量策略的重要组成部分。

  3. 安全语言通常希望在遇到内存不足 (OOM) 情况时中止。SQLite 旨在从 OOM 中优雅地恢复。目前尚不清楚如何在当前的安全语言中实现这一点。

  4. 所有现有的安全语言都是新的。SQLite 开发人员赞赏计算机语言研究人员在努力开发更容易安全编程的语言方面所做的努力。我们鼓励他们继续努力。但当谈到实现 SQLite 时,我们自己对古老而乏味的语言更感兴趣。

尽管如此,SQLite 可能有一天会用 Rust 重写。用 Go 重写 SQLite 的可能性很小,因为 Go 讨厌 assert()。但 Rust 是一个可能性。在 SQLite 用 Rust 重写之前,必须发生的一些先决条件包括

  1. Rust 需要更加成熟,停止快速变化,并进一步朝着古老而乏味的方向发展。
  2. Rust 需要证明它可以用来自所有其他编程语言调用的通用库。
  3. Rust 需要证明它可以生成在模糊的嵌入式设备上运行的目标代码,包括没有操作系统的设备。
  4. Rust 需要获得必要的工具,使人们能够对编译后的二进制文件进行 100% 分支覆盖测试。
  5. Rust 需要一种机制来从 OOM 错误中优雅地恢复。
  6. Rust 需要证明它可以在没有显著速度损失的情况下完成 C 语言在 SQLite 中所做的工作。

如果您是一位“Rustacean”,并且认为 Rust 已经满足了上述先决条件,并且 SQLite 应该用 Rust 重写,那么您被欢迎并鼓励您私下联系 SQLite 开发人员,并阐明您的观点。

本页最后修改于 2022-07-29 00:41:26 UTC