麦当劳荷兰公司在遭遇大量在线批评后,撤下了一则人工智能生成的圣诞广告。该广告将节日描绘成混乱不堪,并暗示人们退避到麦当劳,因此被广泛批评为破坏了圣诞精神。 虽然公司本意是强调节日的压力,但许多观众觉得信息过于消极。该广告使用人工智能创作也引发了争论,一些人认为人工智能是一种扩展创意可能性的工具,另一些人则质疑它对传统广告制作中涉及的人工岗位(如演员和工作人员)的影响。 这一争议紧随可口可乐人工智能生成的假日广告受到类似批评之后,促使该公司今年将重点放在人工智能生成的动物而非人类面孔上。这一事件凸显了人们对人工智能在广告中使用日益增长的担忧,以及它对公众认知和创意产业的潜在影响。
## Go 的内存管理与返回值
从 C/C++ 过来的程序员可能会对 Go 函数返回值的能力感到困惑,因为它避免了 C 中常见的栈/堆问题。在 C 中,返回指向局部变量的指针会导致悬挂指针和未定义行为。
然而,Go 在编译期间使用 **逃逸分析**。如果变量的生命周期超出了它所定义的函数范围(例如,当它被返回时),编译器会自动将其分配到 **堆** 上,而不是栈上。Go 的 **垃圾回收器** 然后管理这块堆内存,确保只要它被引用,它就保持有效。
重要的是,当在 Go 中返回一个切片时,你实际上是在返回切片头(包含指向底层数组、长度和容量的指针)的 *副本*。这个头指向堆分配的数组,该数组在不再被引用之前会持续存在。
这与 C 形成鲜明对比,在 C 中,返回指向栈变量的指针会导致内存立即失效。Go 的设计优先考虑安全性并简化了内存管理,从而实现更简洁的代码,而无需 C 的手动分配/释放复杂性。
## C 和 C++ 中的闭包:性能深度剖析
本文调查了在 C 和 C++ 中实现闭包(数据和指令的结合,泛化函数)的性能影响。虽然闭包在现代语言中很常见,但在 C 中实现高效的闭包面临挑战。核心问题在于需要在不依赖于有问题全局状态(如静态变量)的情况下,将额外数据传递给像 `qsort` 这样的函数。
存在几种方法:重新实现函数以接受用户数据、GNU 嵌套函数、Apple Blocks 和 C++ Lambdas。使用 Knuth 的“Man-or-Boy”测试(强调递归和数据引用)对这些方法进行基准测试,揭示了显著的性能差异。
**主要发现:**
* **C++ Lambdas(直接使用)最快**,受益于编译器在类型信息易于获取时的优化。
* **类型擦除(使用 `std::function`)会引入开销**,但仍然保持合理的效率。
* **Rosetta Code 风格的 Lambdas 令人惊讶地慢**,因为存在过多的数据复制。
* **GNU 嵌套函数目前性能较差**,这是由于与可执行堆栈相关的实现细节所致,从而阻碍了优化。新的基于堆的实现可能会改善这一点。
* **Apple Blocks 提供适度的性能**,受其运行时管理限制。
* **标准的 C 方法处于中等水平**,缺乏更高级技术的优化潜力。
分析强调了编译器优化和最小化数据复制的重要性。作者提倡为 C 提出“宽函数指针”提案,以实现高效的闭包实现并与其他语言互操作。最终目标是为 ISO C 设计一种高性能和标准化的闭包机制。