1

Python 太慢了吗?

 3 years ago
source link: https://www.infoq.cn/article/XC09ISxtCQJR3Asbc9OO
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

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

Python 太慢了吗?

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

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

iQ7FV3U.png!mobile

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=3b1490fa23d3


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK