Python 太慢了吗?

作者 | Anna Anisienia

译者 | 刘雅梦

策划 | 褚杏娟

虽然 Python 比许多编译语言都慢,但它易于使用,而且功能多样。对于许多人来说,语言的实用性要胜过速度。

我是一名 Python 工程师,因此你可能会认为我带有偏见。但是我想澄清一些对 Python 的批评,并反思一下在使用 Python 进行数据工程、数据科学及分析等日常工作中,对速度的担忧是否有必要。

Python 太慢了吗?

我认为,这类问题应该基于特定的上下文或用例来说。与 C 之类的编译语言相比,Python 处理数值的速度慢吗?是的,它是慢的。这一事实人们很多年前就已经知道了,这就是为什么会存在在速度方面起着至关重要作用的 Python 库了,比如 numpy,它的底层使用的是 C。

但是对于所有用例来说,Python 难道都比其他(更难学习和使用的)语言慢得多吗?如果你查看那些为解决特定问题而优化了的 Python 库的性能基准测试,就会发现与编译语言相比,它们的表现是相当不错的。例如,看看 FastAPI 的性能基准测试——显然,作为编译语言的 Go 比 Python 快得多。不过,FastAPI 在构建 REST API 方面还是胜过了一些 Go 库:

Web 框架基准测试——图片由作者提供

旁注:上面的列表中不包含具有更高性能的 C++ 和 Java Web 框架。

同样地,在数据密集型神经成像管道中,对 Dask(用 Python 编写)和 Spark(用 Scala 编写)进行对比时,作者得出了如下结论:

总体而言,我们的结果表明,两个引擎之间的性能没有实质性的差异。

我们应该扪心自问的问题是我们真正需要的是怎样的速度。如果你每天只需触发一次 ETL 作业,则可以不必关心它是需要 20 秒还是 200 秒。然后,你可能更希望代码易于理解、打包和维护,特别是考虑到,与昂贵的引擎耗时相比,计算资源变得越来越便宜了。

代码速度 vs 实用性

从实用的角度来看,在为日常工作而选择编程语言时,我们需要回答几个不同的问题。

用这种语言你能可靠地解决多个业务问题吗?

如果你只关心速度,那就不要用 Python 了。对于各种用例,都有更快的替代方案。Python 的最主要的优点在于它的可读性、易用性,以及可以用它解决各种问题。Python 可以作为一种“粘合剂”,将各种不同的系统、服务和用例连接在一起。

你能找到足够多的懂这门语言的员工吗?

由于 Python 非常易于学习和使用,因此 Python 的用户数一直在不断增长。以前用 Excel 处理数值的业务用户,现在可以非常快速地学会用 Pandas 编码,从而学会在不依赖 IT 资源的情况下自给自足。同时,这也卸下了 IT 和分析部门的负担。同时还缩短了价值实现的时间。

如今,找到懂 Python 并能用这种语言维护 Spark 数据处理应用程序的数据工程师,比找到做同样事情的 Java 或 Scala 工程师要容易得多。许多组织仅仅因为找到会“讲”这种语言的员工的机会更高些,而逐渐在许多用例上都转向使用 Python 来处理了。

相比之下,我知道有些公司迫切需要 Java 或 C# 开发人员来维护现有的应用程序,但是这些语言很难(需要数年的时间才能掌握),而且对于新手程序员来说似乎没有吸引力,因为他们可以利用更简单的语言(比如 Go 或 Python)来获得更多的收入。

不同领域专家之间的协同效应

如果你的公司使用 Python,那么业务用户、数据分析师、数据科学家、数据工程师、后端和 Web 开发人员、DevOps 工程师甚至系统管理员都很有可能会使用相同的语言。这可以在项目中产生协同效应,使来自不同领域的人们可以一起工作,并利用相同的工具。

数据处理中真正的瓶颈是什么?

根据我自己的工作,我通常遇到的瓶颈其实不是语言本身,而是外部资源。更具体地,我们来看几个例子。

写入到关系型数据库

当以 ETL 的方式进行数据处理时,我们最终需要将这些数据加载到某个集中的地方。虽然我们可以利用 Python 中的多线程来更快地(通过使用更多的线程)将数据写入到某些关系型数据库中,但是并行写入数的增加可能会使该数据库的 CPU 容量达到最大值。

实际上,当我使用多线程来加快对 AWS 上 RDS Aurora 数据库的写入时,这种情况就发生过一次。随后我注意到 writer 节点的 CPU 利用率上升得非常高,以至于我不得不通过使用更少的线程来故意降低代码的速度,以确保不会破坏数据库实例。

这意味着 Python 具有并行化和加速许多操作的机制,但是关系型数据库(受 CPU 内核数量的限制)有其局限性,仅通过使用更快的编程语言是不可能解决这个问题的。

调用外部 API

另一个语言本身不是瓶颈的例子是使用外部 REST API(你可能希望从中提取数据以满足数据分析的需求)。虽然我们可以利用并行来加快数据提取的速度,但这可能是徒劳的,因为许多外部 API 限制了我们在特定时间段内可以发出的请求数。因此,你可能经常会发现自己需要故意降低脚本的运行速度,以确保不超过 API 的请求限制:

time.sleep(10)

处理大数据

根据我处理大量数据集的经验,无论使用哪种语言,都无法将真正的“大数据”加载到笔记本电脑的内存中。对于此类用例,你可能需要利用分布式处理框架,如 Dask、Spark、Ray 等。使用单个服务器实例或笔记本电脑时,可以处理的数据量是有限的。

如果你想把实际的数据处理工作转移到一组计算节点上,甚至可能想利用 GPU 实例来进一步加快计算速度,那么 Python 恰好拥有一个庞大的框架生态系统,可以简化这项任务:

  • 你想利用 GPU 来加快数据科学的计算速度吗?使用 Pytorch、Tensorflow、Ray 或 Rapids(甚至是使用 SQL ——BlazingSQL)
  • 你想加快处理大数据的 Python 代码的速度吗?使用 Spark(或 Databricks)、Dask 或 Prefect(在底层抽象化了 Dask)
  • 你想加快数据分析的处理速度吗?使用 fast 专用于内存的列式数据库,仅通过使用 SQL 查询即可确保高速处理。

如果你需要对计算节点集群上进行的数据处理进行编排和监控的话,有几个 Python 编写的工作流管理平台可以使用,它们可以加快数据管道的开发和维护,比如 Apache Airflow、Prefect 或 Dagster。如果你想了解更多相关知识,请查看我之前的文章。

顺便说一句,我可以想象一些抱怨 Python 的人并没有充分利用它,或者可能没有使用恰当的数据结构来解决手头的问题。

总而言之,如果你需要快速处理大量的数据,可能需要更多的计算资源,而不是更快的编程语言,而且有些 Python 库可以方便地将工作分发到数百个节点上。

结      论

在本文中,我们讨论了 Python 是否是当前数据处理领域的真正瓶颈。虽然 Python 比许多编译语言都慢,但它易于使用,而且功能多样。我们注意到,对于许多人来说,语言的实用性要胜过速度。

最后,我们讨论了,至少在数据工程中,语言本身可能不是瓶颈,而是外部系统的限制,以及无论选择哪种编程语言,都无法在单个机器上处理的大量数据。

参考:

[1] TechEmpower:Web 框架基准测试

[2]“数据密集型神经成像管道的 Dask 和 Apache Spark 的性能比较”——Mathieu Dugré,Valérie Hayot-Sasson,Tristan Glatard

原文链接:

https://towardsdatascience.com/is-python-really-a-bottleneck-786d063e2921?gi=3b1490fa23d

本文文字及图片出自 微信公众号

余下全文(1/3)
分享这篇文章:

请关注我们:

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注