来QCon北京,现场感受“纯血鸿蒙”的魅力!席位有限,抓紧报名 了解详情
写点什么

论 Python 语言的三大短板与解决办法

  • 2019-08-22
  • 本文字数:3554 字

    阅读完需:约 12 分钟

论 Python 语言的三大短板与解决办法

多年以来,Python 语言一直受到性能、应用程序打包以及项目管理三大问题的困扰。好在,解决方案即将到来。


虽然 Python 诞生距今已经有 30 年左右,但就在过去几年当中,其受欢迎程度开始快速提升并达到旷古烁今的地步。当下,唯有 Java 及 C 等顶尖高手能够与之匹敌。另外,Python 的普及程度超越了传统编程语言,目前在教学与学术研究当中成为最优编程方法、理想的软件开发起点以及几乎一切技术堆栈的重要组成部分。


遗憾的是,旺盛的人气也放大了 Python 语言的固有缺陷。与其优点一样,Python 也有着不少天生顽疾——性能、应用程序打包与交付,以及项目管理困难,一直是支持者心中永远的痛。虽然这些并不算什么致命缺陷,只能说是 Python 普及道路上的一点障碍;但随着 Julia、Nim、Rust 以及 Go 等其他竞争语言的崛起,解决这些问题已经成为 Python 的燃眉之急。


在本文中,我们将探讨 Python 程序员面对的三大主要挑战,以及 Python 自身、第三方 Python 工具以及库开发者们尝试解决这些挑战的具体方法。

Python 多线程与速度

问题:Python 的总体性能较慢,有限的线程与孱弱的多处理能力成为其未来发展的主要障碍。


Python 长期以来一直更重视编程速度,而非运行速度。考虑到很多开发者习惯于利用 C 或 C++编写高速外部库(例如 NumPy 或者 Numba)以执行 Python 下的性能密集型任务,这样的权衡似乎也没什么大不了。但问题在于,Python 的开箱性能仍然落后于其它语法同样简单、但能够编译为机器码的语言,例如 Nim 或者 Julia。


Python 当中历史最悠久的性能问题之一,在于其对多核心或处理器的资源使用能力不佳。虽然 Python 确实具有线程功能,但却仅限于单一核心。此外,Python 也会尝试通过启动其运行时的子实例以支持多处理,但是针对这些子进程结果的调度与同步往往效率不高。


解决方案:目前,还没有某一种自上而下的整体性解决方案,能够直接搞定 Python 的性能问题。不过,现在已经出现了一系列用于加速 Python 的尝试,其各自都在特定领域做出了一定改进。


下面来看例子:


  • 改善 CPython 的内部行为。 CPython 改进带来了幅度有限但却覆盖面广泛的加速效果。例如,Python 3.8 的 Vectorcall 协议为 Python 对象带来了更快的调用约定。虽然改进效果不算显著,但足以带来具有可测量且可预测的性能提升,而且完全不会破坏向下兼容性;此外,现有 Python 应用程序可直接受益,无需任何代码重写。

  • 改进 CPython 的子解释器功能。 Python 解释器实例的新编程接口现在可以时在各解释器之间实现优雅的数据共享,从而实现多核处理。现在,这项提案已经确定将在 Python 3.9 中面世,相信其还将在后续版本中继续发挥重要作用。

  • 改进多个进程之间的对象共享。Python 当中的多处理机制会为每个核心启动一个新的解释器实例,用以获取最佳性能;但当多个解释器尝试对同一内存对象进行操作时,大部分性能提升都会瞬间作废。目前,以 SahredMemory 类以及新的 pickle 协议为代表的新功能,可以减少解释器之间数据传递所需要的复制或者序列化过程,从根本上消除相关性能问题。


在 Python 之外,也有不少外部项目带来了新的性能提升方法——但同样仅限于特定问题:


  • PyPy。另一种 Python 解释器,PyPy 能够将 Python 即时编译为本机机器码。它在纯 Python 项目当中发挥出色,现在也能很好地兼容比较流行的二进制相关库——例如 NumPy。但其一般更适合长期运行的服务,而非一次性应用程序。

  • Cython。 Cython允许用户逐步将 Python 代码转换为 C 代码。该项目最初是专为科学与数值计算所设计的,但却能够在大多数场景下起效。Cython 最大的缺点在于语法,其使用了独有的语法设置,且转换只能单向进行。Cython 最适合处理“热点”部分代码,这种有针对性的优化方式往往比应用程序整体优化要更合理、也更可行。

  • Numba。 Numba 的即时编译功能可以面向选定功能将 Python 代码编译为机器码。与 Cython 类似,Numba 同样主要用于科学计算,其比较适合就地运行而非对代码进行重新发布。

  • Mypyc。Mypyc 项目目前仍在开发当中,其希望将带有 mypy 类型注释的 Python 代码转换为 C 代码。Mypyc 很有前途,因为其使用到 Python 中的众多原生类型,但目前距离生产应用还有很长的路要走。

  • 经过优化的 Python 发行版。某些第三方 Python 版本(例如英特尔的 Python 发行版)拥有可充分发挥英特尔处理器扩展(例如 AVX512)优势的数学与统计库。需要注意的是,尽管其能够显著加快特定数学函数的执行速度,但却无法实现全面的速度提升。


有经验的 Python 程序员一定还会提到全局解释器锁(GIL)的问题,其负责对指向对象的访问进行序列化,以确保不同线程不会彼此影响到对方的工作负载。从理论上讲,放弃 GIL 可以提高性能。然而,无 GIL Python 基本上丧失了向下兼容能力(特别是在 Python C 扩展方面)。因此到目前为止,所有移除 GIL 的尝试要么已经走进死胡同,要么反而降低了 Python 的性能。


目前另一个正在推进的 Python 计划有望解决不少速度方面的问题,即重构 Python 内部的 C API 实现。众长远来看,提升 API 集的有序程度可以带来诸多性能改进:重新设计或者剔除 GIL、提供可实现强大即时编译的 hook、在解释器实例之间使用更好的数据联合方法等等。

Python 打包与独立可执行文件

问题:即使是在 30 年之后,Python 仍然没能拿到理想的方法,用以将程序或脚本转换为自打包可执行文件,并轻松部署在多种平台之上。


虽然这一目标已经有办法实现,但依靠的主要是第三方工具,而非 Python 的原生功能——此外,其使用难度也不太友好。


最具知名且最受支持的当数PyInstaller,它能够打包多种广受喜爱的高人气第三方扩展,例如 NumPy。不过PyInstaller必须与这些第三方扩展手动保持同步,而这在 Python 的庞大生态系统中无疑是一项艰巨的任务。此外,PyInstaller会生成超大的应用程序包,因为其中捆绑有程序 import 语句中所要求的全部内容,而且并不确定在运行时究竟会用到哪些组件。此外,PyInstaller也无法实现跨平台应用程序打包;我们必须在目标部署平台上进行包创建。


解决方案: 我对 PyInstaller 抱有充分的尊重,但我们可能还需要一套 Python 原生解决方案——无论是内置形式,还是通过标准库提供。它应当允许开发人员以独立二进制文件的形式将 Python 应用程序打包并交付至各类常见的平台。理想情况下,这款内置的打包器应该利用运行时代码覆盖率信息确保仅打包所需的库(而非所有内容),并能够自动与其余 Python 库保持同步。


目前还没有这样的解决方案存在,但关于如何构建此类工具的提示倒是所在多有。PyOxidizer 项目使用 Rust 语言生成能够嵌入 Python 的二进制文件,并将此作为创建独立 Python 应用程序的一种方法。虽然该项目尚处于起步阶段,距离成为完整的应用程序交付方案还有很长的路要走,但这足以证明 Python 生态系统之外的成果也许会成为解决挑战的关键。

Python 安装、软件包管理与项目管理

问题: 有些使用体验太过复杂——对,说的就是为专业级 Python 项目设置工作区、目录结构与基本架构;管理与项目相关的环境、软件包及依赖项;以可重复方式重新分配项目来源;并一次又一次不断进行这个过程。


Rust 与 Go 这两种语言,在初始设计阶段就强调提供一种单一且规范的项目设置方式,并允许开发者在整个生命周期之内对其进行轻松管理。Rust 与 Go 开发人员虽然因此牺牲掉了一定程度的灵活性,但却换来了良好的一致性、可预测性以及可管理性。


Python 提供的安装、软件包以及项目管理工具与方法,随着时间推移而不断积压,并成为 30 年发展周期中的一笔重大负担。其中有用于软件包管理的 pip、用于创建虚拟环境的 venv/virtualenv、用于元管理的 virtualenvwrapper 与 Pipenv、用于生成项目依赖性的 pip-tools、以及用于创建 Python 代码发行版的 distutils 与 setuptools 等。此外,还有负责定义项目其它部分的 setup.py、requirements.txt、setup.cfg、MANIFEST.in 以及 Pipfile 等等。


解决方案: 同样的,我们需要取代这如同一团乱麻的工具与流程大杂烩,由 Python 核心开发团队拿出一套规范性的解决方案,同时确保其能够优雅地迁移一切利用现有方法开发出的项目。当然,这是个很难解决的挑战,但随着 Python 语言变得越来越重要,我们必须努力让它成为一款易于上手、维护简单、一致性强且友好舒适的编程工具。


目前这方面工作已经有所进展。根据 PEP 518 提案,Python 的 build 依赖项被合并为 pyproject.toml 文件格式。而像poetry 这样的第三方工具虽然只能打包现有工具,但已经体现出一体化管理产品的样貌。随着时间的推移,其中一种解决方案也许会脱颖而出、受到整个社区的关注,并成为客观层面甚至是范式性的处理标准。


原文链接:


https://www.infoworld.com/article/3429565/3-major-python-shortcomingsand-their-solutions.html?upd=1566265910128


2019-08-22 10:507306

评论 1 条评论

发布
用户头像
与其想尽办法去处理这些 Python 问题,还不如选择另一个更适合的语言,成本更低。
2019-08-22 11:42
回复
没有更多了
发现更多内容

架构实战营 2-5 微信红包分析随堂测验

西山薄凉

「架构实战营」

Verilog 时延与过程结构

攻城狮Wayne

Verilog语法 Verilog延时 Verilog过程结构

Java开发技术很难吗?

小谷哥

演讲实录|OpenMLDB 与阿里云 MaxCompute 生态集成

第四范式开发者社区

人工智能 数据库 开源 时序数据库 特征

FLStudio21.0.0水果官方中文版发布功能介绍

茶色酒

FLStudio21.0.0

北京同仁堂两大名牌品种亮相帝都

联营汇聚

从React源码来学hooks是不是更香呢

flyzz177

React

react源码分析:babel如何解析jsx

flyzz177

React

前端工程师leetcode算法面试必备-简单的二叉树

js2030code

JavaScript LeetCode

架构实战营 2-6 钱包高可用实战随堂练习

西山薄凉

「架构实战营」

JavaScript刷LeetCode心得

js2030code

JavaScript LeetCode

带你实现react源码的核心功能

flyzz177

React

“智造新未来”欧比护理智造总部奠基仪式

联营汇聚

数据生态第四弹 | OpenMLDB Hive Connector,架构起数据仓库到特征工程的生态桥梁

第四范式开发者社区

人工智能 机器学习 数据库 开源 特征

云计算的六大核心技术,你了解多少?

Finovy Cloud

云技术 云渲染

KCL - 让 Kubernetes 资源清单管理更容易

Peefy

编程 Serverless Kubernetes #开源 #DevOps

2022年11月中国汽车智能网联月度观察

易观分析

汽车 智能网联

易观分析潘玉宇:信贷全流程化监管将成行业发展重点,银行间联合风控程度将逐渐加深

易观分析

银行 普惠金融

从React源码角度看useCallback,useMemo,useContext

flyzz177

React

JDK自带命令优化

@下一站

代码优化 12月日更 12月月更 jvm优化 java程序优化

react源码分析:实现react时间分片

flyzz177

React

RocketMQ 在网易云音乐的实践

Apache RocketMQ

RocketMQ 消息

重磅 | 九科信息入选创新型中小企业(原深圳市专精特新企业)

九科Ninetech

2022-12-12:有n个城市,城市从0到n-1进行编号。小美最初住在k号城市中 在接下来的m天里,小美每天会收到一个任务 她可以选择完成当天的任务或者放弃该任务 第i天的任务需要在ci号城市完成,

福大大架构师每日一题

算法 rust 福大大

React 之 Context 的变迁与背后实现

冴羽

JavaScript 源码分析 前端 前端框架 React

react源码中的生命周期和事件系统

flyzz177

React

用javascript分类刷leetcode3.动态规划(图文视频讲解)

js2030code

JavaScript LeetCode

卡塔尔世界杯出现了半自动越位识别技术、动作轨迹捕捉等黑科技。

汀丶人工智能

12月日更 12月月更 世界杯黑科技

【前端相关】服务端渲染和客户端渲染的比较

No8g攻城狮

CSS css3 前端 js 前端框架

Flink核心组件

穿过生命散发芬芳

flink 12月月更

【IntelliJ IDEA】【SVN】SVN详细的介绍和Idea中如何使用SVN

No8g攻城狮

ide svn Git Submodule git fetch IDEA DeBug

论 Python 语言的三大短板与解决办法_语言 & 开发_Serdar Yegulalp_InfoQ精选文章