Python在生物信息学中的应用:让你的程序运行得更快

这篇具有很好参考价值的文章主要介绍了Python在生物信息学中的应用:让你的程序运行得更快。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

程序运行太慢,想要提速,但不使用复杂的技术如 C 扩展或 JIT 编译器。

解决方案

程序优化的第一准则是“不要优化”第二准则是“不要优化那些不重要的部分”。基于这两个原则,如果你的程序运行得很慢,你得先找出影响性能的问题所在。

多数时候我们发现程序把大量的时间花在几个热点位置,比如处理数据的内层循环。一旦确认了这些热点,就可以使用以下各小节中介绍的技术让程序运行得更快。

使用函数

很多人开始使用 Python 时都是用它来编写一些简单的脚本。最开始时,很容易陷入只管编写代码而不重视程序结构的怪圈。例如:

# somescript.py


import sys
import csv


with open(sys.argv[1]) as f:
    for row in csv.reader(f):


    # Some kind of processing
    pass

一个鲜为人知的事实是,像上面这样定义在全局范围内的代码比定义在函数中的代码要慢。速度的差异与局部变量与全局变量的实现机制有关(涉及局部变量的操作要更快)。因此,如果想让程序运行得更快,可以将脚本中的语句放入函数中即可:

# somescript.py
import sys
import csv


def main(filename):
    with open(filename) as f:
        for row in csv.reader(f):
        # Some kind of processing
            pass


main(sys.argv[1])

运行速度的差异与具体执行的任务有关,但根据经验,提升 15% ~ 30% 的情况很常见。

消除属性访问

每次使用句点操作符(.)来访问对象的属性都会带来开销。在底层,这会触发调用特殊的方法。

通常可以用 from module import name 的导入形式以及选择性地使用绑定方法(bound method)来避免出现属性查询操作。我们用下面的代码片段来加以说明:

import math


def compute_roots(nums):
    result = []
    for n in nums:
        result.append(math.sqrt(n))
    return result


# Test
nums = range(1000000)
for n in range(100):
    r = compute_roots(nums)

当在我们的机器上测试时,这个程序运行了大约 40 秒。现在将 compute_roots() 函数修改为如下形式:

from math import sqrt


def compute_roots(nums):
    result = []
    result_append = result.append
    for n in nums:
        result_append(sqrt(n))
    return result

修改后的版本运行时间大约是 29 秒。唯一不同之处就是消除了属性访问。用 sqrt() 代替了 math.sqrt()。result.append() 方法被赋给一个局部变量 result_append,然后在内部循环中使用它。

但是,必须强调的是,只有在频繁执行的代码中做这些修改才有意义,比如在循环中。因此,这种优化技术适用的场景需要经过精心挑选。

理解变量所处的位置

前述提及,访问局部变量比全局变量要快。对于需要频繁访问的名称,想提高运行速度,可以通过尽量让这些变量尽可能成为局部变量来实现。例如:

import math


def compute_roots(nums):
    sqrt = math.sqrt
    result = []
    result_append = result.append
    for n in nums:
        result_append(sqrt(n))
    return result

在这个版本中,sqrt 方法已经从 math 模块中提取出来并放置在一个局部变量中。如果运行这份代码,执行时间大约是 25 秒,这比上一个版本的 29 秒又有所提升。根本原因就是查找局部变量比全局变量要快。

当使用类时,局部参数同样能起到提速的效果。一般来说,查找像 self.name 这样的值会比访问一个局部变量要慢很多。在内层循环中将需要经常访问的属性移到局部变量中来会很划算。例如:

# Slower
class SomeClass:
    ...
    def method(self):
        for x in s:
            op(self.value)


# Faster
class SomeClass:
    ...
    def method(self):
        value = self.value
    for x in s:
        op(value)

避免不必要的抽象

装饰器(decorator)、属性(property)或者描述符(descriptor)包装过的代码,运行速度通常会变慢。参考以下代码:

class A:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    @property
    def y(self):
        return self._y
    @y.setter
    def y(self, value):
        self._y = value

测试一下:

>>> from timeit import timeit
>>> a = A(1,2)
>>> timeit('a.x', 'from __main__ import a')
0.07817923510447145
>>> timeit('a.y', 'from __main__ import a')
0.35766440676525235
>>>

使用内建的容器

内建的数据类型比如字符串、元组、列表、集合以及字典都是用 C 语言实现的,速度非常快。如果需要构建自己的数据结构作为替代(例如链表、二叉树等),想在性能上达到内建的速度几乎不可能,因此还是尽量使用内建的数据结构吧。

避免产生不必要的数据结构或者拷贝动作

有时候程序员可能会创建一些不必要的数据结构,比如下面的代码:

values = [x for x in sequence]
squares = [x*x for x in values]

也许这里的想法是首先将一些值收集到一个列表中,然后使用列表推导来执行操作。不过,第一个列表完全没有必要,可以简单的像下面这样写:

squares = [x*x for x in sequence]

与此相关,还要注意下那些对Python的共享数据机制过于偏执的程序所写的代码。有些人并没有很好的理解或信任Python的内存模型,滥用 copy.deepcopy() 之类的函数。通常在这些代码中是可以去掉复制操作的。

讨论

在进行优化之前,有必要研究一下使用的算法。选择一个复杂度为 O(n log n) 的算法要比你去调整一个复杂度为 O(n**2) 的算法所带来的性能提升要大得多。

如果优化代码势在必行,那么请从整体考虑。作为一般准则,不要对程序的每一个部分都去优化,因为这些修改会导致代码难以阅读和理解。你应该专注于优化产生性能瓶颈的地方,比如内部循环。

还要注意一些小的优化的结果。比如下面创建字典的两种方式:

a = {
    'name' : 'AAPL',
    'shares' : 100,
    'price' : 534.22
}


b = dict(name='AAPL', shares=100, price=534.22)

后面一种写法更简洁一些(你不需要在关键字上输入引号)。不过,如果你将这两个代码片段进行性能测试对比时,会发现使用 dict() 的方式会慢了3倍。看到这个,你是不是有冲动把所有使用 dict() 的代码都替换成第一种。不过,聪明的程序员只会关注他应该关注的地方,比如内部循环。在其他地方,这点性能损失没有什么影响。

如果你的优化要求比较高,本节的这些简单技术满足不了,那么你可以研究下基于即时编译(JIT)技术的一些工具。例如,PyPy 工程是 Python 解释器的另外一种实现,它会分析你的程序运行并对那些频繁执行的部分生成本机机器码。它有时候能极大的提升性能,通常可以接近 C 代码的速度。不过可惜的是,到写这本书为止,PyPy 还不能完全支持 Python3。因此,这个是你将来需要去研究的。你还可以考虑下 Numba 工程, Numba 是一个在你使用装饰器来选择 Python 函数进行优化时的动态编译器。这些函数会使用LLVM被编译成本地机器码。它同样可以极大的提升性能。但是,跟 PyPy 一样,它对于 Python 3 的支持现在还停留在实验阶段。

最后我引用John Ousterhout说过的话作为结尾:“最好的性能提升就是从不工作转变为可以工作”。直到你真的需要优化的时候再去考虑它。确保你程序正确的运行通常比让它运行更快要更重要一些(至少开始是这样的)。

参考

  • 《Python Cookbook》第三版

  • http://python3-cookbook.readthedocs.org/zh_CN/latest/

关于简说基因

  • 生信平台

    Galaxy中国(UseGalaxy.cn)致力于打造中国人的云上生物信息基础设施。大量在线工具免费使用。无需安装,用完即走。活跃的用户社区,随时交流使用心得。文章来源地址https://www.toymoban.com/news/detail-830378.html

  • 生信培训

    简说基因的生信培训班,荣获学员的一致好评。如果你也对生物信息学感兴趣,欢迎来跟简说基因,学真生信。

  • 生信分析

    我们能够承接所有 NGS 组学数据分析业务,包括但不限于 WGS / WES / RNA-seq 等。基因组组装、注释,以及各种重测序业务都可以与简说基因合作。

到了这里,关于Python在生物信息学中的应用:让你的程序运行得更快的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 轻松搞定Spring集成缓存,让你的应用程序飞起来!

    主页传送门:📀 传送   Spring 提供了对缓存的支持,允许你将数据存储在缓存中以提高应用程序的性能。Spring 缓存抽象基于 Java Caching API,但提供了更简单的编程模型和更高级的功能。   Spring 集成缓存提供了一种方便的方式来使用缓存,从而提高应用程序的性能。Spr

    2024年02月07日
    浏览(49)
  • 【超详细】深入探究Java中的线程安全,让你的程序更加可靠~

    我们将从以下四个问题入手,对Java的多线程问题抽丝剥茧。 什么是线程安全? 如何实现线程安全? 不同的线程安全实现方法有什么区别? 如何实现HashMap线程安全? 1. 什么是线程安全? 线程安全指的是多个线程并发访问共享资源时,不会出现数据不一致或其他意外情况的

    2023年04月24日
    浏览(24)
  • 让你的代码动起来:Python进度条神器tqdm详解及应用实例

    各位Python高手,今天我要给大家介绍一个好用的库,它就是: tqdm tqdm在阿拉伯语中的意思是 \\\"进展\\\",所以这个库也被称为 \\\"快速进展条\\\"。不得不说,这个名字真的很有创意! 让我们想象一下,你正在运行一个耗时的数据处理任务或者训练一个复杂的深度学习模型。你坐在那

    2024年02月07日
    浏览(51)
  • 实战演示:使用Python编写人脸识别测试代码,让你的应用拥有智能感知能力

    人脸识别是计算机视觉领域的一个重要应用。它使用计算机算法来识别和验证面部特征,通常用于安全认证、视频监控、人脸比对等方面。近年来,随着深度学习技术的发展,人脸识别的性能得到了极大的提升,成为了智能感知应用中的重要一环。在这篇文章中,我们将使用

    2024年02月12日
    浏览(31)
  • 图形学中的抗锯齿讨论以及在unity中的应用

    抗锯齿(Anti-Aliasing)是图形学中,很重要的一个部分。本文旨在做一些分析总结,并对平时不理解的细节,做了调研,但毕竟不是做GPU行家,所以有不对的地方,欢迎拍砖^^。 下图,是一个在unity中,不开启抗锯齿的情况下的渲染效果,可以看到,边沿区域,例如黄色块的边沿

    2024年02月15日
    浏览(32)
  • 线性代数在计算机图形学中的应用

    文章背景:本学期我学习了计算机图形学,我发现背后都是由线性代数的知识作为支撑的,于是我想把目前我了解到的一些数学知识总结出来。另外,本文在举例时主要采用计算机游戏的场景来进行举例,以更好地说明这些数学概念或公式的应用。 (本文章为课程作业)  

    2024年02月04日
    浏览(35)
  • 【计算机图形学】 线性代数在图形学中的应用

    🙋‍♂️ 作者:海码007 📜 专栏:计算机图形学专栏 💥 标题:【计算机图形学】 线性代数在图形学中的应用 ❣️ 寄语:对知识永远有兴趣! 🎈 最后: 文章作者技术和水平有限,如果文中出现错误,希望大家能指正 为什么要总结一下线性代数?因为计算机图形学中有很

    2024年03月10日
    浏览(49)
  • 第四篇【传奇开心果系列】Python的自动化办公库技术点案例示例:深度解读Pandas生物信息学领域应用

    生物信息学是一门将计算机科学和生物学相结合的跨学科领域,旨在利用计算机技术和统计学方法来处理、分析和解释生物学数据。在生物信息学研究中,研究人员处理的数据种类繁多,包括基因组数据、蛋白质数据、生物医学图像数据等。 Pandas 是一个基于 Python 编程语言的

    2024年03月09日
    浏览(73)
  • 信息系统安全审计,这种系统让你的电脑彻底安全!!

    信息系统安全性审计的主要目标是审查企业信息系统和电子数据的安全性、可靠性、可用性、保密性等。 一是预防来自互联网对信息系统的威胁,二是预防来自企业内部对信息系统的危害。 ——百度百科 信息系统安全涉及多个层面和维度,确保数据的机密性、完整性和可用

    2024年04月10日
    浏览(32)
  • 这种新的Facebook Messenger群发方式,让你的信息更有价值!

    随着社交媒体的迅速发展,Facebook已成为人们分享信息、建立联系和开展业务的重要平台之一。在这个数字时代,如何有效地传达信息并与目标受众建立联系成为了关键的挑战。 而最近引入的Facebook Messenger群发方式为我们提供了一种全新的机会,让我们的信息更有价值,更有

    2024年02月06日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包