顶级服务器端Swift框架与Node.js的基准测试

方法与注释

为什么要使用博客和JSON?

最简单的是,博客不仅仅是返回“ Hello,world!”,而且JSON是一个非常常见的用例。 好的基准测试在每个框架上都需要类似的负载,并且需要更多的负载才能在屏幕上打印两个单词。

保持相同

我试图坚持的主要主题之一是使所有博客尽可能彼此相似,同时仍按照每个框架的样式和语法进行开发。 许多结构(如内容生成)会逐字重复,因此每个框架都可以使用相同的数据模型,但是诸如URL路由之类的方面有时会完全不同,以适应每个框架的语法和样式。

细微差异

服务器端Swift框架之间有一些细微的差异需要注意。

  • 如果Kitura和Zewo的绝对文件路径中有空格,则在构建时都会遇到问题。 在任何框架中,Xcode在使用绝对文件路径中的空格进行构建时也存在问题。
  • Zewo使用的是05–09-a Swift快照,这意味着它在发布模式下构建时遇到问题,必须在调试模式下运行。 因此,所有Zewo测试都是使用Zewo构建并在调试模式下运行的(没有发行优化)。
  • 静态文件处理是服务器端Swift框架之间争论的焦点。 Vapor和Zewo都建议使用Nginx作为静态文件处理的代理,然后将该框架作为后端的处理能力。 Perfect建议使用其内置的处理程序,并且我还没有看到IBM关于他们对此主题的观点的任何评论。 由于这项研究不是关于框架如何与已建立的服务器应用程序(如Nginx)一起工作的,因此每个框架都在本地使用静态文件处理。 如果选择考虑这一点,则可能在Vapor和Zewo上都可以实现更好的性能。 这也是我包含JSON测试的第二个原因。
  • [9月1日添加了更新的结果] Zewo是单线程应用程序。 您可以通过在每个可用CPU上运行一个应用程序实例来获得额外的性能,因为它们遵循并发而非多线程模型。 为了本研究的目的,每个应用程序仅运行一个实例。
  • 工具链。 每个框架都在构建与Apple不同的开发快照工具链。 在最终测试时,它们是:

    –完美的DEVELOPMENT-SNAPSHOT-2016-08–24-a
    – Vapor&Kitura的DEVELOPMENT-SNAPSHOT-2016-07–25-a
    – Zewo的DEVELOPMENT-SNAPSHOT-2016-05–09-a
  • Vapor具有用于运行发行版的特殊语法。 如果仅执行二进制文件,则将获得一些额外的控制台日志记录,这些日志记录将有助于开发和调试过程。 那有一点点开销。 要以发布模式运行Vapor,您需要添加
  --env =生产 

到可执行文件。 即

  .build / release / App --env =生产 
  • [9月1日添加了更新的结果]使用Zewo时,即使不能在05-09-a工具链上以发布模式快速构建,也可以通过传递以下参数来添加一些发布模式优化:
 迅速建立-Xswiftc -O 
  • Node.js / Express不生成,也不区分调试/发布
  • 静态文件处理包含在Vapor的默认中间件中。 如果您不使用静态文件并且要优化速度,则必须包括(就像我在VaporJSON中所做的那样):
  drop.middleware = [] 

为什么选择Node.js / Express?

我决定在Node.js中使用Express框架添加博客的变体。 这是一个很好的比较,因为它的语法与Server-Side Swift非常相似,并且被广泛使用。 它有助于建立一个良好的基线,以显示Swift可以给人留下深刻的印象。

开发博客

在某个时候,我开始称其为“追赶弹跳球”。 当前的服务器端Swift框架和Swift 3都处于非常活跃的开发中,并且每个框架都与以前的版本相比有很多更改。 所有服务器端Swift框架以及Apple的Swift团队的频繁发布使这种情况更加严重。 目前他们还没有一个特别完整的文档,所以我非常感谢框架团队的成员和Server-Side Swift社区的贡献。 对于无数社区成员和框架团队在此过程中给予我的帮助,我也深表感谢。 那真是太有趣了,我会不加思索地再做一次。

附带说明一下,即使许可证没有要求注明出处,但我还是很高兴注意到源中包含的所有随机免版税图片均来自Pixbay,并由我随机选择。 这样的资源使演示项目更加容易。

托管与环境

为了最大程度地减少环境差异,我购买了2012年的Mac Mini,并对其进行了全新安装的El Capitan(10.11.6)。 之后,我下载并安装了Xcode 8 beta 6,并将命令行工具设置为Xcode8。从那里我安装了swiftenv,安装了必要的快照,克隆了存储库,并以发布模式再次干净地构建了每个博客,其中可能。 我从来没有一次跑过一个,并且在测试之间每个都停止并重新启动。 测试服务器规格为:

为了进行开发,我使用了2015 rMBP。 我在这里运行了构建时间测试,因为这是我的现实开发机器,并且最有意义。 我使用wrk来获得基准,然后使用机器之间的thunderbolt 2电缆在thunderbolt桥上进行了测试。 使用雷电桥接器可确保您拥有令人难以置信的带宽,并且不对路由器的局限性进行基准测试,而不必进行手头的工作。 在一台计算机上为博客提供服务,并使用另一台功能更强大的计算机来生成负载也更加可靠,以确保您能够胜任服务器的工作,因此可以确定这不是限制。 这也为您提供了一致的测试环境,因此我可以说每个博客都在相同的硬件和相同的条件下运行。 出于好奇,我的机器规格为:

标杆注意事项

为了进行基准测试,我决定使用十分钟测试,其中包含四个线程,每个线程包含20个连接。 四秒未测试。 十分钟是获取大量数据的合理时间范围,并且在四个线程上运行20个连接对于博客而言是沉重的负担,但不是一个沉重的负担。

源代码

如果您想探索项目的源代码或进行任何自己的测试,我将用于测试的代码合并到一个存储库中,该存储库位于:

https://github.com/rymcol/Server-Side-Swift-Benchmarking

详细结果

建立时间

我认为先看看构建时间会很有趣。 构建时间在日常开发中可以发挥重要作用,尽管与框架的性能没有多大关系,但我认为探索实数与等待时的感觉可能会很有趣。

运行了什么

对于每个框架,

 迅速建立--clean = dist 

接着

 快速构建 

运行,然后进行第二次测试

 快速构建-干净 

然后:

 快速构建 

这既考虑了完整的构建,包括使用SPM提取依赖关系,也考虑了具有已下载依赖关系的常规,干净构建。

它是如何运行的

这是在我的本地2015 rMBP上运行的,所有构建均以调试模式完成,因为这是开发Swift软件时的正常过程。

建立时间结果