0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

以聪明的方式对Python进行编码

星星科技指导员 来源:嵌入式计算设计 作者:Mohammed Billoo 2022-11-17 15:45 次阅读

我们利用Percepio的Tracealyzer来深入了解同一算法的两种不同实现的性能。具体来说,我们确定使用迭代函数而不是递归函数实现生成斐波那契数列的算法性能更高。我们不需要在序列中生成大量条目并测量时间来识别性能差异;相反,我们能够使用 Tracealyzer 让我们深入了解实现的性能,同时在序列中仅生成 10 个条目。

由于斐波那契序列生成器是在 Python 中实现的,让我们进一步扩展一下。关于StackOverflow的一些主要问题与特定算法的最有效和“Pythonic”实现有关。在本文中,我们将研究一个流行的操作:反转列表。

根据以下关于 StackOverflow 的问题,在反转列表时,关于一个实现相对于另一个实现的性能存在一些争论。为了深入了解差异,我们可以在一个简单的应用程序中实现这两种技术,如下面的列表所示;我们还包括必要的源代码,以捕获 Tracealyzer 评估每个实现的性能所需的标记:

import logging

def example():

list_basis = list(range(10))

logging.basicConfig()

logger = logging.getLogger(‘my-logger’)

logger.info(‘Start’)

reverse_list = reversed(list_basis)

logger.info(‘Stop’)

logger.info(‘Start’)

reverse_list = list_basis[::-1]

logger.info(‘Stop’)

if __name__ == ‘__main__’:

example()

我们创建了一个包含 10 个元素的列表,并使用内置的“反转”函数以及 Python 中称为“切片”的技术来反转列表。切片只是获取列表中的某些元素并将它们返回到新列表;在我们的例子中,我们正在切片整个列表,但向后遍历。

与上一篇博客文章一样,我们可以创建一个 LTTng 会话,运行我们的 Python 脚本,在 Tracealyzer 中打开生成的跟踪,并评估结果:

我们可以看到,使用反向函数的实现大约需要 475 微秒,使用切片的实现大约需要 360 微秒。

让我们看看当我们将初始列表中的元素数量增加 10 倍时会发生什么,从而得到一个由 100 个元素组成的列表:

import lttngust

import logging

def example():

list_basis = list(range(100))

logging.basicConfig()

logger = logging.getLogger(‘my-logger’)

logger.info(‘Start’)

reverse_list = reversed(list_basis)

logger.info(‘Stop’)

logger.info(‘Start’)

reverse_list = list_basis[::-1]

logger.info(‘Stop’)

if __name__ == ‘__main__’:

example()

同样,我们重新运行必要的步骤来创建 LTTng 会话,运行我们的应用程序,并在 Tracealyzer 中打开生成的跟踪,它向我们显示了下图:

虽然我们看到与以前相同的模式,其中切片技术比反向函数表现更好,但我们可以看到,与只有 10 个元素的结果相比,这两种机制的绝对时间几乎减少了一半。这很有趣,因为我们预计,与 100 个元素的情况相比,在 10 个元素的情况下,这两种技术所花费的时间应该更少。让我们通过首先更新 Python 脚本来收集更多数据,以允许我们以自动方式收集更多数据:

import lttngust

import logging

import sys

def example(list_size):

list_basis = list(range(list_size))

logging.basicConfig()

logger = logging.getLogger(“my-logger”)

logger.info(“Start”)

reverse_list = reversed(list_basis)

logger.info(“Stop”)

logger.info(“Start”)

reverse_list = list_basis[::-1]

logger.info(“Stop”)

if __name__ == ‘__main__’:

example(int(sys.argv[-1]))

在上面的例子中,我们只是允许自己在列表中传入我们想要的元素数量。然后我们可以创建以下 bash 脚本,这将允许我们执行 Python 应用程序,连续给它一个 10 和 100 的参数,收集使用反向函数和切片方法反转列表所需的时间,并存储该数据;脚本将循环浏览每个测试 10 次。

#!/bin/bash

set -e

list_compare() {

echo “Running test with a list size of $1 elements”

lttng create

lttng enable-event --kernel sched_switch

lttng enable-event --python my-logger

lttng start

python3 list_compare.py $1

lttng stop

lttng destroy

}

for i in {1..10}

do

list_compare 10

cp -r ~/lttng-traces/auto* “/home/pi/percepio/elements_10_trace_$i”

chown -R pi: “/home/pi/percepio/elements_10_trace_$i”

mv ~/lttng-traces/auto* ~/lttng-traces/archive/

list_compare 100

cp -r ~/lttng-traces/auto* “/home/pi/percepio/elements_100_trace_$i”

chown -R pi: “/home/pi/percepio/elements_100_trace_$i”

mv ~/lttng-traces/auto* ~/lttng-traces/archive/

done

当我们在 Tracealyzer 中打开生成的迹线并绘制图表时,我们会看到以下趋势:

黄色和橙色图表示 10 个元素列表的反转时间,绿色和深红色图表示 100 个元素列表的反转时间相同。我们可以看到一些实例,其中 10 个元素列表反转的执行时间与 100 个元素结果的执行时间一致。类似地,我们可以看到,有一个实例减少了反转 100 个元素列表的执行时间,并且与反转 10 个元素列表的执行时间相同。但是,总的来说,我们可以看到反转 10 个元素列表的执行时间大约是反转 100 个元素列表所需时间的一半。

也许我们在前一个案例中观察到了这些异常之一?让我们分析包含 1000 个元素的结果:

同样,我们看到相同的模式,与使用反向功能相比,使用切片技术花费的时间更少。但是,即使我们再次将列表中的元素数量增加了 10 倍(达到惊人的 1000 个元素),每个实现的时间与 100 个元素的时间大致相同,与只有 10 个元素相比,时间仍然是一半的时间。

让我们将列表大小增加到 100k 个元素并观察结果:

以前我们观察到切片技术花费的时间大约是反向函数的一半,而在这里我们可以看到相反的情况。事实上,对于 100k 个元素的列表大小,切片技术花费的时间大约延长了 15 倍!

总之,我们从这个简单的练习中获得了一些宝贵的见解。首先,与反向函数相比,切片技术似乎花费的时间更少,对于“几个”元素的列表大小(最多 1000)。但是,当我们将列表大小增加到 100k 个元素时,我们可以看到切片技术比反向函数花费大约 15 倍的时间。其次,当我们运行较小大小列表的多次迭代时,我们确实注意到反转包含 100 个元素的列表的时间与反转包含 10 个元素的列表的时间大致相同的实例;然而,总体趋势是,反转包含 10 个元素的列表比反转包含 100 个元素的列表花费的时间更少,这是意料之中的!我们可以更详细地分析Tracealyzer捕获的痕迹,以了解观察到的异常的原因。

这里的关键要点是,Percepio 的 Tracealyzer 使我们能够在没有太多仪器基础设施的情况下执行这种详细的分析;我们能够辨别出大约 100 微秒的性能数字!

由于Python一直是机器学习的流行语言,因此我们必须拥有一个工具,可以快速将一种算法的性能与另一种算法的性能进行比较。我们可以开发一些小函数来隔离我们要评估的算法,并使用 Tracealyzer 为我们提供有关算法在不同维度的性能的必要见解。Tracealyzer还可以快速发现可能需要进一步分析的异常行为。

审核编辑:郭婷

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 函数
    +关注

    关注

    3

    文章

    4235

    浏览量

    61965
  • python
    +关注

    关注

    53

    文章

    4753

    浏览量

    84070
收藏 人收藏

    评论

    相关推荐

    如何在程序中编码方式来控制JBOSS

    上一节已经学习了CLI命令行来控制JBOSS,如果想在程序中编码方式来控制JBOSS,可以参考下面的代码,实际上在前面的文章,用代码控制Jboss上的DataSource,已经有所接触了,API与CLI是完全等价的,一个是人工
    发表于 08-05 06:24

    围绕神经网络知识和网络应用方式展开Python和R语言实战编码

    本文将围绕神经网络构建的基础知识展开,并集中讨论网络的应用方式,用Python和R语言实战编码
    的头像 发表于 12-28 10:07 4489次阅读
    围绕神经网络知识和网络应用<b class='flag-5'>方式</b>展开<b class='flag-5'>Python</b>和R语言实战<b class='flag-5'>编码</b>

    学习Python的最佳方式取决于你个人的学习方式

    了 Django 和其他流行的 Python Web 框架,为 Python Web 开发人员提供了关键技能。该站点还为初学者,中级 Python 开发人员和其他编程语言的有经验的编码
    的头像 发表于 03-21 09:28 2453次阅读
    学习<b class='flag-5'>Python</b>的最佳<b class='flag-5'>方式</b>取决于你个人的学习<b class='flag-5'>方式</b>

    CRC算法原理和CRC编码的实现方式与使用Verilog对CRC编码进行描述

    泛的是CRC-32 标准。本文将以CRC-32 为例,说明CRC 编码的实现方式以及如何用verilog 语言对CRC 编码进行描述。
    发表于 08-06 16:39 36次下载
    CRC算法原理和CRC<b class='flag-5'>编码</b>的实现<b class='flag-5'>方式</b>与使用Verilog对CRC<b class='flag-5'>编码</b><b class='flag-5'>进行</b>描述

    如何使用Python Turtle进行编码

     可以做更多的事情,本教程只是为了让您领略并继续前进。有关更多信息,请查看Python Turtle文档,
    的头像 发表于 01-29 17:51 2289次阅读

    NVIDIA推出适用于Python的VPF,简化开发GPU加速视频编码/解码

    NVIDIA推出了适用于Python的开源视频处理框架“VideoProcessingFramework”(VPF)。据悉,VPF 是一组开源的C ++库和Python绑定,可与其封闭源代码Codec SDK进行交互。该框架的功
    的头像 发表于 12-18 14:25 6861次阅读

    AI和聪明的算法之间的区别在于它的编程方式

    AI和聪明的算法之间的区别在于它的编程方式。如果您是最终用户或消费者,则可以在两点上与计算机系统或技术进行交互:1 /起点-收集输入并输入到系统中;
    的头像 发表于 04-11 09:51 3190次阅读

    Python的学习和使用经验说明

    本文对Python 的版本选择, IDE 选择及编码的解决方案进行了一番详细的描述,实为Python 开发人员必读的Python 学习经验心
    发表于 09-01 16:46 16次下载
    <b class='flag-5'>Python</b>的学习和使用经验说明

    懒惰的方式对电阻器进行排序

    电子发烧友网站提供《懒惰的方式对电阻器进行排序.zip》资料免费下载
    发表于 10-27 10:28 2次下载
    <b class='flag-5'>以</b>懒惰的<b class='flag-5'>方式</b>对电阻器<b class='flag-5'>进行</b>排序

    Python对txt进行读写操作

    Python对txt进行读写操作
    的头像 发表于 01-11 15:16 739次阅读

    QM:现代方式对Arduino进行编程

    电子发烧友网站提供《QM:现代方式对Arduino进行编程.zip》资料免费下载
    发表于 06-15 10:21 0次下载
    QM:<b class='flag-5'>以</b>现代<b class='flag-5'>方式</b>对Arduino<b class='flag-5'>进行</b>编程

    Python中的默认编码

    ####1. Python源代码文件的执行过程 我们都知道,磁盘上的文件都是以二进制格式存放的,其中文本文件都是以某种特定编码的字节形式存放的。对于程序源代码文件的字符编码是由编辑器指定的,比如
    的头像 发表于 07-05 16:11 1026次阅读
    <b class='flag-5'>Python</b>中的默认<b class='flag-5'>编码</b>

    Python字符编码转换

    UNICODE字符串可以与任意字符编码的字节进行相互转换,如图: 那么大家很容易想到一个问题,就是不同的字符编码的字节可以通过Unicode相互转换吗?答案是肯定的。 Python2中
    的头像 发表于 07-05 16:25 967次阅读
    <b class='flag-5'>Python</b>字符<b class='flag-5'>编码</b>转换

    利用Python发送邮件的 3 种方式

    Python 发送邮件的 3 种方式 2. 准备 126 邮箱为例,在编码之前,我们需要开启 SMTP 服务 然后,手动新增一个授权码 其中,账号、授权码和服务器地址用于连接登录
    的头像 发表于 11-02 11:37 828次阅读

    ARM中的编码方式与寻址方式有何不同?

    ARM中的编指方式与寻址方式有何不同? ARM处理器是一种广泛应用的微处理器架构,被广泛用于移动设备、嵌入式设备以及智能家居等领域。在ARM架构中,编码方式和寻址
    的头像 发表于 01-29 18:10 556次阅读