字符串性能 - Windows 10 下的 Python 2.7 与 Python 3.4 对比 Ubuntu

2024-03-15

Use case
一个简单的函数,用于检查特定字符串是否在另一个字符串中的位置为 3 的倍数(请参阅此处现实世界的例子 https://en.wikipedia.org/wiki/Stop_codon,在 DNA 序列中寻找终止密码子)。

功能
sliding_window:取长度为 3 的字符串与搜索字符串进行比较,如果相同则向前移动 3 个字符。
incremental_start:尝试查找搜索字符串,如果找到的位置不是3的倍数,则尝试查找找到的位置之后的下一个位置。

请注意:示例数据只是为了确保每个函数都必须遍历完整的字符串,性能与真实数据或随机数据类似。

Results

  • Python 2.7: 最初的sliding_window使用该函数可以将函数提高约 39 倍incremental_startWindows 10 上的 Python2.7 中。Ubuntu 上的性能改进略有下降,约 34 倍、约 37 倍、约 18 倍(VM、AWS、本机),但仍在同一范围内。
  • Python 3.4: sliding_window比 Python2.7 慢(在 Windows 上为 1.8 倍,在所有 Ubuntu 上为 1.4 倍或 1.5 倍),但是incremental_start在所有 Ubuntu 上性能下降了 4、5、1.7 倍(VM、AWS、本机),而在 Windows 上几乎没有变化。
  • Windows 与 Ubuntu
    Python2.7:虚拟化的 Ubuntu 实现这两个功能所需的时间更少(约 20-30%),原生 Ubuntu 的速度慢了大约 25%incremental_start, while sliding_window速度提高了 40%。
    Python3: the sliding_window函数完成所需的时间更少 (~50%),而incremental_start速度变慢约 2-3 倍。

问题

  • 是什么导致 Python 2 与 Python 3 在 Linux 和 Windows 上的性能差异?
  • 如何预测这种行为并调整代码以获得最佳性能?

Code

import timeit

text = 'ATG' * 10**6
word = 'TAG'

def sliding_window(text, word):
    for pos in range(0, len(text), 3):
        if text[pos:pos + 3] == word:
            return False
    return True

def incremental_start(text, word):
    start = 0
    while start != -1:
        start = text.find(word, start + 1)
        if start % 3 == 0:
            return False
    return True

#sliding window
time = timeit.Timer(lambda: sliding_window(text, word), setup='from __main__ import text, word').timeit(number=10)
print('%3.3f' % time)

#incremental start
time = timeit.Timer(lambda: incremental_start(text, word), setup='from __main__ import text, word').timeit(number=500)
print('%3.3f' % time)

Tables

Ubuntu vs Windows    VM     AWS    Native   
Python2.7-Increment  79%    73%    126% 
Python2.7-Sliding    70%    70%    60%                  
Python3.4-Increment  307%   346%   201% 
Python3.4-Sliding    54%    59%    48%  

Py2 vs 3    Windows    VM    AWS    Native
Increment   105%       409%  501%   168%
Sliding     184%       143%  155%   147%

Absolute times in seconds
                 Win10   Ubuntu  AWS     Native
Py2.7-Increment  1.759   1.391   1.279   2.215 
Py2.7-Sliding    1.361   0.955   0.958   0.823 

Py3.4-Increment  1.853   5.692   6.406   3.722 
Py3.4-Sliding    2.507   1.365   1.482   1.214 

Details
Windows 10:本机 Windows、32 位 Python 3.4.3 或 2.7.9、i5-2500、16GB RAM
Ubuntu虚拟机:14.04,运行在Windows主机上,64位Python 3.4.3,Python 2.7.6,4核,4GB RAM
AWS:14.04、AWS 微实例、64 位 Python 3.4.3、Python 2.7.6
原生 Ubuntu:14.04、64 位 Python 3.4.3、Python 2.7.6、i5-2500、16GB 内存 [与 Win10 机器相同]


Update

正如英加兹所建议的xrange and bytes使用Python3.4后,性能略有提高,但在Ubuntu上性能仍然大幅下降。罪魁祸首似乎是find当 Ubuntu 和 Py3.4 组合时,速度要慢得多(与从源代码编译的 Py3.5 相同)。这似乎与 Linux 风格相关,在 Debian 上 Py2.7 和 Py3.4 表现相同,在 RedHat 上 Py2.7 比 Py3.4 快得多。
为了更好的比较,Py3.4现在在Windows10和Ubuntu上的64位中使用。 Win10上仍然使用Py27。

import timeit, sys

if sys.version_info >= (3,0):
    from builtins import range as xrange

def sliding_window(text, word):
    for pos in range(0, len(text), 3):
        if text[pos:pos + 3] == word:
            return False
    return True

def xsliding_window(text, word):
    for pos in xrange(0, len(text), 3):
        if text[pos:pos + 3] == word:
            return False
    return True

def incremental_start(text, word):
    start = 0
    while start != -1:
        start = text.find(word, start + 1)
        if start % 3 == 0:
            return False
    return True

text = 'aaa' * 10**6
word = 'aaA'
byte_text = b'aaa' * 10**6
byte_word = b'aaA'

time = timeit.Timer(lambda: sliding_window(text, word), setup='from __main__ import text, word').timeit(number=10)
print('Sliding, regular:      %3.3f' % time)

time = timeit.Timer(lambda: incremental_start(text, word), setup='from __main__ import text, word').timeit(number=500)
print('Incremental, regular:  %3.3f' % time)

time = timeit.Timer(lambda: sliding_window(byte_text, byte_word), setup='from __main__ import byte_text, byte_word').timeit(number=10)
print('Sliding, byte string:  %3.3f' % time)

time = timeit.Timer(lambda: incremental_start(byte_text, byte_word), setup='from __main__ import byte_text, byte_word').timeit(number=500)
print('Incremental, bytes:    %3.3f' % time)

time = timeit.Timer(lambda: xsliding_window(byte_text, byte_word), setup='from __main__ import byte_text, byte_word').timeit(number=10)
print('Sliding, xrange&bytes: %3.3f' % time)

time = timeit.Timer(lambda: text.find(word), setup='from __main__ import text, word').timeit(number=1000)
print('simple find in string: %3.3f' % time)


Win10-py27  Wi10-py35   VM-py27  VM-py34
1.440       2.674       0.993    1.368 
1.864       1.425       1.436    5.711 
1.439       2.388       1.048    1.219 
1.887       1.405       1.429    5.750 
1.332       2.356       0.772    1.224 
3.756       2.811       2.818    11.361 

尽管您正在测量相同代码的速度,但代码中的结构是不同的。

A. range2.7 中是type 'list',3.4 中的范围是class 'range'

B. 'ATG' * 10**6 在 2.7 中是字节字符串,在 3.4 中是 unicode 字符串

如果满足以下条件,您可以尝试生成更兼容的结果:a) 对 2.7 变体使用 xrange,b) 使用bytes两个示例中的字符串:b'ATG'或两个示例中的 unicode 字符串。

Update

我怀疑性能差异源于主要因素:a) 32 位与 64 位,b) C 编译器。

所以,我做了测试:

  1. ActiveState Python 2.7.10 32位
  2. ActiveState Python 2.7.10 64位
  3. 官方发行版Python 2.7.11 32位
  4. 官方发行版Python 2.7.11 64位
  5. Python 2.7.6 64位上Windows 10 上的 Ubuntu https://blogs.windows.com/buildingapps/2016/03/30/run-bash-on-ubuntu-on-windows/
  6. pypy-5.1.1-win32

我所期望的

我期望:

  • 64位版本会比较慢
  • ActiveState会快一点
  • PyPy 速度更快
  • Windows 10 上的 Ubuntu - ???

Results

Test                    as32b   as64b   off32b   off64b  ubw64b  pypy5.1.1
Sliding, regular:       1.232   1.230   1.281    1.136   0.951   0.099  
Incremental, regular:   1.744   1.690   2.219    1.647   1.472   2.772
Sliding, byte string:   1.223   1.207   1.280    1.127   0.926   0.101
Incremental, bytes:     1.720   1.701   2.206    1.646   1.568   2.774
Sliding, xrange&bytes:  1.117   1.102   1.162    0.962   0.779   0.109
simple find in string:  3.443   3.412   4.607    3.300   2.487   0.289

Windows 10 上的获胜者是……由 GCC 4.8.2 为 Linux 编译的 Ubuntu Python!

这个结果完全出乎我的意料。

32 vs 64:变得无关紧要。

PyPy:一如既往的超快,除非不是这样。

我无法解释这个结果,OP问题变得不像看起来那么简单。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

字符串性能 - Windows 10 下的 Python 2.7 与 Python 3.4 对比 Ubuntu 的相关文章

  • TensorFlow:带有轴选项的 bincount

    在 TensorFlow 中 我可以使用 tf bincount 获取数组中每个元素的计数 x tf placeholder tf int32 None freq tf bincount x tf Session run freq feed
  • 从 Python 下载/安装 Windows 更新

    我正在编写一个脚本来自动安装 Windows 更新 我可以将其部署在多台计算机上 这样我就不必担心手动更新它们 我想用 Python 编写这个 但找不到任何关于如何完成此操作的信息 我需要知道如何搜索更新 下载更新并从 python 脚本安
  • 无故运行测试时 PyCharm 抛出“AttributeError: 'module' object has no attribute”

    因此 我有一个 Django REST Framework 项目 有一天它无法在 PyCharm 中运行测试 从命令行我可以使用它们来运行它们paver or the manage py直接地 曾经有一段时间 当我们没有在文件顶部导入类的超
  • Python 是解释型的还是编译型的,或者两者兼而有之?

    据我了解 An 解释的语言是由解释器 将高级语言转换为机器代码然后执行的程序 实时运行和执行的高级语言 它一次处理一点程序 A compiled语言是一种高级语言 其代码首先由编译器 将高级语言转换为机器代码的程序 转换为机器代码 然后由执
  • Python 使用 Gstreamer 访问 USB 麦克风时遇到问题,以便在 Raspberry Pi 上使用 Pocketsphinx 执行语音识别

    所以Python的表现就好像它根本听不到我的麦克风发出的任何声音 问题就在这里 我有一个Python 2 7 假设使用的脚本Gstreamer通过以下方式访问我的麦克风并为我进行语音识别口袋狮身人面像 我在用着脉冲音频我的设备是树莓派 我的
  • 编辑 Jupyter Notebook 时 VS Code 中缺少“在选择中查找”

    使用 Jupyter Notebook 时 VSCode 中缺少 在选择中查找 按钮 它会减慢开发速度 所以我想请问有人知道如何激活它吗 第一张图显示了在 python 文件中的搜索 替换 第二张图显示了笔记本电脑中缺少的按钮 Python
  • 在相同任务上,Keras 比 TensorFlow 慢

    我正在使用 Python 运行斩首 DCNN 本例中为 Inception V3 来获取图像特征 我使用的是 Anaconda Py3 6 和 Windows7 使用 TensorFlow 时 我将会话保存在变量中 感谢 jdehesa 并
  • 如何从 JSON 响应重定向?

    所以我尝试使用 Flask 和 Javascript 上传器 Dropzone 上传文件并在上传完成后重定向 文件上传正常 但在烧瓶中使用传统的重定向 return redirect http somesite com 不执行任何操作 页面
  • 迭代列表的奇怪速度差异

    我创建了两个重复两个不同值的长列表 在第一个列表中 值交替出现 在第二个列表中 一个值出现在另一个值之前 a1 object object 10 6 a2 a1 2 a1 1 2 然后我迭代它们 不对它们执行任何操作 for in a1 p
  • Python:我不明白 sum() 的完整用法

    当然 我明白你使用 sum 与几个数字 然后它总结所有 但我正在查看它的文档 我发现了这一点 sum iterable start 第二个参数 start 的作用是什么 这太尴尬了 但我似乎无法通过谷歌找到任何示例 并且对于尝试学习该语言的
  • 如何用 kevent() 替换 select() 以获得更高的性能?

    来自Kqueue 维基百科页面 http en wikipedia org wiki Kqueue Kqueue 在内核和用户空间之间提供高效的输入和输出事件管道 因此 可以修改事件过滤器以及接收待处理事件 同时每次主事件循环迭代仅使用对
  • 使用 NLP 进行地址分割

    我目前正在开发一个项目 该项目应识别地址的每个部分 例如来自 str Jack London 121 Corvallis ARAD ap 1603 973130 输出应如下所示 street name Jack London no 121
  • 以编程方式使用 Sphinx 特定指令解析 .rst 文件

    我希望能够在 Python 中解析基于 sphinx 的 rst 以便进一步处理和检查 就像是 import sphinx p sphinx parse path to file rst do something with p 似乎在 do
  • 从 python 检测 macOS 中的暗模式

    我正在编写一个 PyQt 应用程序 我必须添加一个补丁 以便在启用暗模式的 Macos 上可以读取字体 app QApplication Fix for the font colours on macos when running dark
  • sqlite3从打印数据中删除括号

    我创建了一个脚本 用于查找数据库第一行中的最后一个值 import sqlite3 global SerialNum conn sqlite3 connect MyFirstDB db conn text factory str c con
  • 带有 RotatingFileHandler 的 Python 3 记录器超出 maxBytes 限制

    我使用以下代码来限制日志文件的大小 最小示例 import logging from logging handlers import RotatingFileHandler Set up logfile and message loggin
  • 哪些属性有助于运行时 .Net 性能?

    我正在寻找可用于通过向加载器 JIT 编译器或 ngen 提供提示来确保 Net 应用程序获得最佳运行时性能的属性 例如我们有可调试属性 http msdn microsoft com en us library k2wxda47 aspx
  • 计算互相关函数?

    In R 我在用ccf or acf计算成对互相关函数 以便我可以找出哪个移位给我带来最大值 从它的外观来看 R给我一个标准化的值序列 Python 的 scipy 中是否有类似的东西 或者我应该使用fft模块 目前 我正在这样做 xcor
  • bs4 `next_sibling` VS `find_next_sibling`

    我在使用时遇到困难next sibling 并且类似地与next element 如果用作属性 我不会得到任何返回 但如果用作find next sibling or find next 然后就可以了 来自doc https www cru
  • python 中的 after() 与 update()

    我是 python 新手 开始使用 tkinter 作为画布 到目前为止 我使用 update 来更新我的画布 但还有一个 after 方法 谁能给我解释一下这个函数 请举个例子 两者之间有什么区别 root after integer c

随机推荐

  • 如何使用Javascript触发CSS“悬停状态”? [复制]

    这个问题在这里已经有答案了 当用户将鼠标悬停在元素上时 CSS 悬停状态 将触发 我们如何使用 Javascript 将元素设置为 悬停状态 是否可以 如果您可以接受使用 focus您可以使用以下命令来代替悬停 var links docu
  • 如何根据条件应用Spring消息转换器?

    我有一个控制器 其响应是驼峰式 json 值 现在我们正在用新版本重写代码 所需的响应位于snake case中 我添加了一个消息转换器并修改了对象映射器来设置setPropertyNamingStrategy PropertyNaming
  • 有没有集成CouchDb和Solr的项目?

    我希望能够使用 Solr 搜索 CouchDB 数据库 有没有提供这样的集成的项目 我还知道 CouchDB Lucene 有没有办法让 Solr 融入其中 Thanks 考虑到它是多么容易 自己推出会更有意义 首先 您需要决定使用哪种 S
  • $.mobile.silentScroll 在 worklight 应用程序中不起作用

    我正在使用 IBM 的 worklight 框架开发一个应用程序 其中我使用 jquery 移动库进行编码 不幸的是 当我使用 mobile silentScroll滚动 它没有效果 它不起作用 有人遇到过这个问题吗 在其他工作中 如何在w
  • PowerShell安装NuGet,显示无法访问互联网,但实际上可以

    我按照中提到的步骤进行操作在代理后面使用 PowerShell http woshub com using powershell behind a proxy 配置我的代理服务器 netsh winhttp set proxy IP Por
  • Pygame 或 Python 中的透明窗口

    我正在尝试为我的游戏制作一个透明窗口作为启动屏幕 图像具有透明度 但我无法使窗口透明 例如在其后面看到屏幕 桌面等 我发现的所有内容都不能使用 pygame 我可以从中提取任何外部库来实现这一点吗 顺便提一句 这完全是一个Linux项目 所
  • Django FileField 在上传后移动文件

    围绕这一主题有几个问题 但我发现没有一个适合我想做的事情 我希望能够将文件上传到模型 并使用 pk 等模型实例属性将该文件保存在一个合适的位置 我知道这些东西会在之后设置model save 所以我需要编写一个自定义保存来执行此操作 但我无
  • 如何配置 docker 文件以像 perl 一样运行 cgi 脚本

    我有这个文件 索引 php Dockerfile conf myawesomesite conf cgi bin helloworld pl 在 conf myawesomesite conf 中
  • PHP 页面加载/刷新到准确位置

    我想做的是通过 href 链接将用户传递到 php 脚本 然后将他们传回与单击链接之前完全相同的位置 就像页面尚未刷新一样 有谁知道这是否或如何可能 谢谢 使用 HTML 您可以得到以下内容 p a href script php Send
  • 如何在 MongoDB 中处理小于 1970 的日期

    我有一个包含 生日 字段的文档 该字段的值也可能低于 01 01 1970 我该如何处理这个问题 例如 birthday gt newMongoDate strtotime 31 10 1968 这将创建一个 生日 值 1 1 1970 1
  • Tomcat 上的 SSL 证书 - 别名无法识别密钥

    想知道是否有人可以告诉我我在哪里搞砸了 我有一个 keytool 创建的密钥库 一个来自 Thawte 的主证书 辅助证书和 ssl 证书 我最初使用 openssl 创建了 CSR 然后使用记录的过程将私钥转换为 PKCS12 以导入到密
  • 将一行复制一定次数,然后每次将 30 分钟添加到时间戳(就像序列一样)

    样本数据 ID Location Type Trip End Number of periods 1298 Residential 02 01 2022 05 30 48 1298 Residential 03 01 2022 05 30
  • 可以在 PHP 中测试变量是否是静态的吗?

    PHP 中是否可以测试变量是否是静态的 我正在尝试创建一个神奇的方法 get它还查看静态变量 我发现property exists 当变量也是静态时返回 true 但我需要使用 代替 gt 我会期待吗 可以通过反射测试变量是否是静态的 cl
  • 构建多部分响应

    考虑到多个 HTTP 请求的响应 我必须从中构建一个多部分响应 我面临的问题是如何在最终的多部分响应中设置单个响应的响应标头 为了 例如 HttpClient client new HttpClient HttpRequestMessage
  • 带标头的 Alamofire POST 请求

    我正在尝试在 Swift 中使用 Alamofire 发出带有标头的发布请求 然而 我不断得到方法调用中的额外参数错误 我正在使用 Alamofire 4 5 版本 我无法找出错误 请查找附件中的代码 let headers Authori
  • 流星中的 Bootstrap 3 模态未显示

    我试图让 bootstrap 3 模态弹出流星应用程序 但没有成功 一切似乎都已就位 我已经在这里和其他地方搜索过 但它根本行不通 HTML 是
  • 如何使用 xml 设置颜色可绘制的圆角半径?

    在android网站上 有一个关于颜色绘图的部分 http developer android com guide topics resources available resources html colordrawableresourc
  • 计算成员中的 WHERE 子句

    我面临一些通过比较维度值来计算值的问题 我有 3 个维度 数据类型 客户 产品 和一个度量 GrossSales 如果我想要 ProductID 1 2 3 且 Dataype 4 5 6 的 GrossSales MDX 查询是什么 这里
  • 在数据库中存储年份[关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 年份数据的最佳 PostgreSQL 数据类型是什么 例如 2006 年或 1847 年 TEXT SMALLINT DATE 理想情况下
  • 字符串性能 - Windows 10 下的 Python 2.7 与 Python 3.4 对比 Ubuntu

    Use case一个简单的函数 用于检查特定字符串是否在另一个字符串中的位置为 3 的倍数 请参阅此处现实世界的例子 https en wikipedia org wiki Stop codon 在 DNA 序列中寻找终止密码子 功能 sl