IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> Python 3.14 会比 C++ 更快! -> 正文阅读

[Python知识库]Python 3.14 会比 C++ 更快!

对最新的、令人印象深刻的 Python 3.11 的基准测试

知乎@春阳CYang

Python是数据科学(DS)和机器学习(ML)中最常用的脚本语言之一。根据PopularitY of Programming Languages,Python 是谷歌搜索最多的语言。除了它是一种将各种 DS/ML 解决方案整合在一起的优秀胶水语言之外,它还有许多其他的库可以对数据做各种各样的事情。

大约在一个月前,我们得到了新的 Python 年度发行版 - 3.11版。我对这个新版本感到非常兴奋,因为这个版本的主要特点是速度显著提高。

在各种社交媒体上,我们已经看到很多人测试新版本的帖子,他们的测试结果令人震惊。但了解 Python3.11 真正有多快的最好方法是自己运行测试。

在这篇文章中,我将分享我对 Python3.11 的逐步分析。所有代码都可以在 我的 github 上找到。

alt

对编程语言进行基准测试一点也不简单。当你觉得 x 比 y 快时,你应该对结果持怀疑态度。算法的一个实现可能比 x 好,而另一个实现比 y 好。对于我们的基准测试来说,我们尽可能的希望它能简单一些,因为我们正在用 Python 测试 Python,但我们可能已经从语言中选择了一些影响不大的元素。考虑到这一点,我想介绍我用于基准测试的算法:基因组组装算法 DNA K-mers。

基因组组装算法 DNA K-mers。

这个算法的思想很简单,DNA 是一个长串序列,称为核苷酸。在 DNA 中,有 4 种核苷酸以字母 A、C、G 和 T 表示。人类(或者更准确地说是智人)有 30 亿个核苷酸对。例如,人类 DNA 的一小部分可能是:

ACTAGGGATCATGAAGATAATGTTGGTGTTTGTATGGTTTTCAGACAATT

在这个例子中,如果想从这个字符串中选择任何 4 个连续的核苷酸(即字母),它将是一个长度为 4 的k-mer(我们称之为4-mer)。以下是从示例中导出的一些 4-mers 示例。

ACTA,?CTAG,?TAGG,?AGGG,?GGGA,?etc.

对于本文,让我们生成所有可能的 13-mers。从数学上讲,这是一个置换问题。因此,我们有 413(=67108864)可能的 13-mers。我用一个简单的算法在 C++ 和 Python 中生成结果。让我们看看不同 Python 版本和 C++ 的比较结果。

对比 Python 和 C++ 的结果

Python 不同版本的测试

def?K_mer(k:?int)?->?None:
????def?convert(c):
????????if?c?==?"A":
????????????return?"C"
????????if?c?==?"C":
????????????return?"G"
????????if?c?==?"G":
????????????return?"T"
????????if?c?==?"T":
????????????return?"A"

????print("开始")

????opt?=?"ACGT"
????s?=?""
????s_last?=?""
????len_str?=?k

????for?i?in?range(len_str):
????????s?+=?opt[0]

????for?i?in?range(len_str):
????????s_last?+=?opt[-1]

????pos?=?0
????counter?=?1
????while?s?!=?s_last:
????????counter?+=?1
????????#?你可以取消下一行的注释来查看所有的?k-mers.
????????#?print(s)
????????change_next?=?True
????????for?i?in?range(len_str):
????????????if?change_next:
????????????????if?s[i]?==?opt[-1]:
????????????????????s?=?s[:i]?+?convert(s[i])?+?s[i?+?1?:]??#?type:?ignore
????????????????????change_next?=?True
????????????????else:
????????????????????s?=?s[:i]?+?convert(s[i])?+?s[i?+?1?:]??#?type:?ignore
????????????????????break

????#?你可以取消下一行的注释来查看所有的?k-mers.
????#?print(s)
????print("生成?k-mers?的数量:?{}".format(counter))
????print("完成!")

上面这个脚本已经可以运行了,但是我们希望使用它来测试 Python 的各种版本,而不仅仅是当前安装(或激活)的版本。测试多个 Python 版本的最简单方法是使用 Docker。Python 维护许多 docker 镜像。当然,所有受支持的版本,也包括一些生命周期结束(EOL)的版本,如 2.7 或 3.2。要使用 Docker,您需要安装它。在 Linux 和 Mac 上相对容易,在 Windows 上我不太确定,但可能也不难。我建议只安装 docker CLI,桌面对我来说太臃肿了。要在容器化的 Python 环境中运行本地脚本,请运行:

docker?run?-it?--rm?\
??-v?$PWD/your_script.py:/your_script.py?\
??python:3.11-rc-slim?\
??python?/yourscript.py

为了自动化各种版本的测试,我们当然也会使用 Python。这个脚本只需启动一个子进程,以启动具有特定 Python 版本的容器,然后收集结果。没什么特别的:

import?time
import?argparse


def?K_mer(k:?int)?->?None:
????def?convert(c):
????????if?c?==?"A":
????????????return?"C"
????????if?c?==?"C":
????????????return?"G"
????????if?c?==?"G":
????????????return?"T"
????????if?c?==?"T":
????????????return?"A"

????print("开始")

????opt?=?"ACGT"
????s?=?""
????s_last?=?""
????len_str?=?k

????for?i?in?range(len_str):
????????s?+=?opt[0]

????for?i?in?range(len_str):
????????s_last?+=?opt[-1]

????pos?=?0
????counter?=?1
????while?s?!=?s_last:
????????counter?+=?1
????????#?你可以取消下一行的注释来查看所有的?k-mers.
????????#?print(s)
????????change_next?=?True
????????for?i?in?range(len_str):
????????????if?change_next:
????????????????if?s[i]?==?opt[-1]:
????????????????????s?=?s[:i]?+?convert(s[i])?+?s[i?+?1?:]??#?type:?ignore
????????????????????change_next?=?True
????????????????else:
????????????????????s?=?s[:i]?+?convert(s[i])?+?s[i?+?1?:]??#?type:?ignore
????????????????????break

????#?你可以取消下一行的注释来查看所有的?k-mers.
????#?print(s)
????print("生成?k-mers?的数量:?{}".format(counter))
????print("完成!")


def?run_test(k:?int)?->?None:
????start_time?=?time.time()
????K_mer(k)
????print(f"{(time.time()?-?start_time):.4f}秒")


def?main():
????"""Main?loop?in?arg?parser."""
????parser?=?argparse.ArgumentParser()
????parser.add_argument(
????????"-k",
????????"--k_mer",
????????help="DNA?序列长度",
????????type=int,
????????default=13,
????)

????args?=?parser.parse_args()

????run_test(args.k_mer)


if?__name__?==?"__main__":
????main()

运行这些测试时,根据处理器的不同,绝对值会因机器而异(它占用大量 CPU)。以下是最近 7 个主要 Python 版本的结果:

新版本?Python?3.11?花费了?31.9501?秒.
Python?3.5?花费了?63.3502?秒.(Python?3.11?比它快?98.3%?)
Python?3.6?花费了?62.9635?秒.(Python?3.11?比它快?97.1%?)
Python?3.7?花费了?57.5806?秒.(Python?3.11?比它快?80.2%?)
Python?3.8?花费了?59.0129?秒.(Python?3.11?比它快?84.7%?)
Python?3.9?花费了?54.4991?秒.(Python?3.11?比它快?70.6%?)
Python?3.10?花费了?47.7407?秒.(Python?3.11?比它快?49.4%?)

Python 3.11 的基准测试平均耗时 6.46 秒。与之前的版本(3.10)相比,这几乎快了 37%。非常令人印象深刻!版本 3.9 和 3.10 之间的差异大致相同,使 3.11 几乎快了 70%!把所有的点在下图中画出来。

alt

C++ 的测试

当谈到速度时,我们总是有一个人说:如果你想要速度,为什么不使用 C。

C is much faster that Python! — that one guy

下面我们用 C++ 实现上面的 K-mers 算法。

#include?<iostream>
#include?<string>

using?namespace?std;

char?convert(char?c)
{
????if?(c?==?'A')?return?'C';
????if?(c?==?'C')?return?'G';
????if?(c?==?'G')?return?'T';
????if?(c?==?'T')?return?'A';
????return?'?';
}


int?main()
{
????cout?<<?"开始"?<<?endl;?

????string?opt?=?"ACGT";
????string?s?=?"";
????string?s_last?=?"";
????int?len_str?=?13;
????bool?change_next;

????for?(int?i=0;?i<len_str;?i++)
????{
????????s?+=?opt[0];
????}

????for?(int?i=0;?i<len_str;?i++)
????{
????????s_last?+=?opt.back();
????}

????int?pos?=?0;
????int?counter?=?1;
????while?(s?!=?s_last)
????{???
????????counter?++;
????????//?You?can?uncomment?the?next?line?to?see?all?k-mers.
????????//?cout?<<?s?<<?endl;??
????????change_next?=?true;
????????for?(int?i=0;?i<len_str;?i++)
????????{
????????????if?(change_next)
????????????{
????????????????if?(s[i]?==?opt.back())
????????????????{
????????????????????s[i]?=?convert(s[i]);
????????????????????change_next?=?true;
????????????????}?else?{
????????????????????s[i]?=?convert(s[i]);
????????????????????break;
????????????????}
????????????}
????????}
????}

????//?You?can?uncomment?the?next?line?to?see?all?k-mers.
????//?cout?<<?s?<<?endl;
????cout?<<?"生成?k-mers?的数量:?"?<<?counter?<<?endl;
????cout?<<?"完成!"?<<?endl;?
????return?0;
}

众所周知,C++ 是一种编译语言,因此,我们需要先编译源代码,然后才能使用它。安装了 C++ 的基础软件之后,可以键入:

g++?-o?k_mer?k_mer.c

编译后,只需运行构建可执行文件。输出应如下所示:

生成?k-mers?的数量:?67108864????花费时间:?8.92218?秒
生成?k-mers?的数量:?67108864????花费时间:?9.01176?秒
生成?k-mers?的数量:?67108864????花费时间:?8.88735?秒
生成?k-mers?的数量:?67108864????花费时间:?8.9754?秒

每个循环平均需要 8.945 秒来计算。 我们必须同意这一点,因为它真的很快。只花了 8.945 秒就完成了我们以前用 Python 编程的相同循环。让我们把它作为一条线添加到前面的绘图中,如下图所示。

alt

现在,在对前面的数字进行了长时间的分析之后,我们清楚地看到了Python的发展势头。自版本 3.9 以来,Python 的速度提高了约 35%。Python开发人员提到,接下来的两个版本将有显著的速度提升,因此,我们可以假设这个速度将保持不变(是的,超级安全的假设)。

现在的问题是,在这种势头得到修正的情况下,Python 何时才能超越 C++ 时代。为此,我们当然可以使用推断来预测下一个 Python 版本的运行时间。这些可以在下图中看到:

alt

结果真是太棒了!如果保持这种迭代的速度,Python 3.14 将比 C++ 更快。 alt

声明

虽然这些 Python3.5 到 Python3.11 的基准测试是有效的,但这种推断当然只是一个玩笑。XKCD 风格的画图也是另一种提醒;-)

如果您想在各种 Python 版本上运行这些测试或您自己的测试,请在我的 Github 页面上下载代码。

如果您有任何意见,请告诉我!

本文由 mdnice 多平台发布

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-10-08 20:37:01  更:2022-10-08 20:40:55 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/26 2:41:30-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计