Rumah pembangunan bahagian belakang Tutorial Python PyPy 和 CPython 的性能比较测试

PyPy 和 CPython 的性能比较测试

Oct 18, 2016 pm 01:33 PM
cpython pypy python prestasi ujian

最近我在维基百科上完成了一些数据挖掘方面的任务。它由这些部分组成:

解析enwiki-pages-articles.xml的维基百科转储;

把类别和页存储到MongoDB里面;

对类别名称进行重新分门别类。

我对CPython 2.7.3和PyPy 2b的实际任务性能进行了测试。我使用的库是:

redis 2.7.2

pymongo 2.4.2

此外CPython是由以下库支持的:

hiredis

pymongo c-extensions

测试主要包含数据库解析,所以我没预料到会从PyPy得到多大好处(何况CPython的数据库驱动是C写的)。

下面我会描述一些有趣的结果。


抽取维基页名


我需要在所有维基百科的类别中建立维基页名到page.id的联接并存储重新分配好的它们。最简单的解决方案应该是导入enwiki-page.sql(定义了一个RDB表)到MySQL里面,然后传输数据、进行重分配。但我不想增加MySQL需求(有骨气!XD)所以我用纯Python写了一个简单的SQL插入语句解析器,然后直接从enwiki-page.sql导入数据,进行重分配。

这个任务对CPU依赖更大,所以我再次看好PyPy。

/ time

PyPy 169.00s 用户态 8.52s 系统态 90% CPU

CPython 1287.13s 用户态 8.10s 系统态 96% CPU

我也给page.id->类别做了类似的联接(我笔记本的内存太小了,不能保存供我测试的信息了)。


从enwiki.xml中筛选类别


为了方便工作,我需要从enwiki-pages-articles.xml中过滤类别,并将它们存储相同的XML格式的类别。因此我选用了SAX解析器,在PyPy和CPython中都适用的包装器解析。对外的原生编译包(同事在PyPy和CPython 中) 。

代码非常简单:

class WikiCategoryHandler(handler.ContentHandler):
    """Class which detecs category pages and stores them separately
    """
    ignored = set(('contributor', 'comment', 'meta'))
  
    def __init__(self, f_out):
        handler.ContentHandler.__init__(self)
        self.f_out = f_out
        self.curr_page = None
        self.curr_tag = ''
        self.curr_elem = Element('root', {})
        self.root = self.curr_elem
        self.stack = Stack()
        self.stack.push(self.curr_elem)
        self.skip = 0
  
    def startElement(self, name, attrs):
        if self.skip>0 or name in self.ignored:
            self.skip += 1
            return
        self.curr_tag = name
        elem = Element(name, attrs)
        if name == 'page':
            elem.ns = -1
            self.curr_page = elem
        else:   # we don't want to keep old pages in memory
            self.curr_elem.append(elem)
        self.stack.push(elem)
        self.curr_elem = elem
  
    def endElement(self, name):
        if self.skip>0:
            self.skip -= 1
            return
        if name == 'page':
            self.task()
            self.curr_page = None
        self.stack.pop()
        self.curr_elem = self.stack.top()
        self.curr_tag = self.curr_elem.tag
  
    def characters(self, content):
        if content.isspace(): return
        if self.skip == 0:
            self.curr_elem.append(TextElement(content))
            if self.curr_tag == 'ns':
                self.curr_page.ns = int(content)
  
    def startDocument(self):
        self.f_out.write("<root>\n")
  
    def endDocument(self):
        self.f_out.write("<\root>\n")
        print("FINISH PROCESSING WIKIPEDIA")
  
    def task(self):
        if self.curr_page.ns == 14:
            self.f_out.write(self.curr_page.render())
  
  
class Element(object):
    def __init__(self, tag, attrs):
        self.tag = tag
        self.attrs = attrs
        self.childrens = []
        self.append = self.childrens.append
  
    def __repr__(self):
        return "Element {}".format(self.tag)
  
    def render(self, margin=0):
        if not self.childrens:
            return u"{0}<{1}{2} />".format(
                " "*margin,
                self.tag,
                "".join([&#39; {}="{}"&#39;.format(k,v) for k,v in {}.iteritems()]))
        if isinstance(self.childrens[0], TextElement) and len(self.childrens)==1:
            return u"{0}<{1}{2}>{3}</{1}>".format(
                " "*margin,
                self.tag,
                "".join([u&#39; {}="{}"&#39;.format(k,v) for k,v in {}.iteritems()]),
                self.childrens[0].render())
  
        return u"{0}<{1}{2}>\n{3}\n{0}</{1}>".format(
            " "*margin,
            self.tag,
            "".join([u&#39; {}="{}"&#39;.format(k,v) for k,v in {}.iteritems()]),
            "\n".join((c.render(margin+2) for c in self.childrens)))
  
class TextElement(object):
    def __init__(self, content):
        self.content = content
  
    def __repr__(self):
        return "TextElement" def render(self, margin=0):
        return self.content
Salin selepas log masuk

Element和TextElement元素包换tag和body信息,同时提供了一个方法来渲染它。

下面是我想要的PyPy和CPython比较结果。

/ time

PyPy 2169.90s

CPython 4494.69s

我很对PyPy的结果很吃惊。

计算有趣的类别集合


我曾经想要计算一个有趣的类别集合——在我的一个应用背景下,以Computing类别衍生的一些类别为开始进行计算。为此我需要构建一个提供类的类图——子类关系图。

结构类——子类关系图


这个任务使用MongoDB作为数据来源,并对结构进行重新分配。算法是:

for each category.id in redis_categories (it holds *category.id -> category title mapping*) do:
    title = redis_categories.get(category.id)
    parent_categories = mongodb get categories for title
    for each parent_cat in parent categories do:
        redis_tree.sadd(parent_cat, title) # add to parent_cat set title
Salin selepas log masuk

抱歉写这样的伪码,但我想这样看起来更加紧凑些。

所以说这个任务仅把数据从一个数据库拷贝到另一个。这里的结果是MongoDB预热完毕后得出的(不预热的话数据会有偏差——这个Python任务只耗费约10%的CPU)。计时如下:

/ time

PyPy 175.11s 用户态 66.11s 系统态 64% CPU

CPython 457.92s 用户态 72.86s 系统态 81% CPU


遍历redis_tree(再分配过的树)


如果我们有redis_tree数据库,仅剩的问题就是遍历Computing类别下所有可实现的结点了。为避免循环遍历,我们需要记录已访问过的结点。自从我想测试Python的数据库性能,我就用再分配集合列来解决这个问题。

/ time

PyPy 14.79s 用户态 6.22s 系统态 69% CPU 30.322 总计

CPython 44.20s 用户态 13.86s 系统态 71% CPU 1:20.91 总计

说实话,这个任务也需要构建一些tabu list(禁止列表)——来避免进入不需要的类别。但那不是本文的重点。


结论

进行的测试仅仅是我最终工作的一个简介。它需要一个知识体系,一个我从抽取维基百科中适当的内容中得到的知识体系。

PyPy相比CPython,在我这个简单的数据库操作中,提高了2-3倍的性能。(我这里没有算上SQL解析器,大约8倍)

多亏了PyPy,我的工作更加愉悦了——我没有改写算法就使Python有了效率,而且PyPy没有像CPython一样把我的CPU弄挂了,以至于一段时间内我没法正常的使用我的笔记本了(看看CPU时间占的百分比吧)。

任务几乎都是数据库操作,而CPython有一些加速的乱七八糟的C语言模块。PyPy不使用这些,但结果却更快!

我的全部工作需要大量的周期,所以我真高兴能用PyPy。


Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

PHP dan Python: Paradigma yang berbeza dijelaskan PHP dan Python: Paradigma yang berbeza dijelaskan Apr 18, 2025 am 12:26 AM

PHP terutamanya pengaturcaraan prosedur, tetapi juga menyokong pengaturcaraan berorientasikan objek (OOP); Python menyokong pelbagai paradigma, termasuk pengaturcaraan OOP, fungsional dan prosedur. PHP sesuai untuk pembangunan web, dan Python sesuai untuk pelbagai aplikasi seperti analisis data dan pembelajaran mesin.

Memilih antara php dan python: panduan Memilih antara php dan python: panduan Apr 18, 2025 am 12:24 AM

PHP sesuai untuk pembangunan web dan prototaip pesat, dan Python sesuai untuk sains data dan pembelajaran mesin. 1.Php digunakan untuk pembangunan web dinamik, dengan sintaks mudah dan sesuai untuk pembangunan pesat. 2. Python mempunyai sintaks ringkas, sesuai untuk pelbagai bidang, dan mempunyai ekosistem perpustakaan yang kuat.

Python vs JavaScript: Keluk Pembelajaran dan Kemudahan Penggunaan Python vs JavaScript: Keluk Pembelajaran dan Kemudahan Penggunaan Apr 16, 2025 am 12:12 AM

Python lebih sesuai untuk pemula, dengan lengkung pembelajaran yang lancar dan sintaks ringkas; JavaScript sesuai untuk pembangunan front-end, dengan lengkung pembelajaran yang curam dan sintaks yang fleksibel. 1. Sintaks Python adalah intuitif dan sesuai untuk sains data dan pembangunan back-end. 2. JavaScript adalah fleksibel dan digunakan secara meluas dalam pengaturcaraan depan dan pelayan.

Bolehkah kod studio visual digunakan dalam python Bolehkah kod studio visual digunakan dalam python Apr 15, 2025 pm 08:18 PM

Kod VS boleh digunakan untuk menulis Python dan menyediakan banyak ciri yang menjadikannya alat yang ideal untuk membangunkan aplikasi python. Ia membolehkan pengguna untuk: memasang sambungan python untuk mendapatkan fungsi seperti penyempurnaan kod, penonjolan sintaks, dan debugging. Gunakan debugger untuk mengesan kod langkah demi langkah, cari dan selesaikan kesilapan. Mengintegrasikan Git untuk Kawalan Versi. Gunakan alat pemformatan kod untuk mengekalkan konsistensi kod. Gunakan alat linting untuk melihat masalah yang berpotensi lebih awal.

Adakah sambungan vscode berniat jahat? Adakah sambungan vscode berniat jahat? Apr 15, 2025 pm 07:57 PM

Sambungan kod VS menimbulkan risiko yang berniat jahat, seperti menyembunyikan kod jahat, mengeksploitasi kelemahan, dan melancap sebagai sambungan yang sah. Kaedah untuk mengenal pasti sambungan yang berniat jahat termasuk: memeriksa penerbit, membaca komen, memeriksa kod, dan memasang dengan berhati -hati. Langkah -langkah keselamatan juga termasuk: kesedaran keselamatan, tabiat yang baik, kemas kini tetap dan perisian antivirus.

Boleh kod vs dijalankan di Windows 8 Boleh kod vs dijalankan di Windows 8 Apr 15, 2025 pm 07:24 PM

Kod VS boleh dijalankan pada Windows 8, tetapi pengalaman mungkin tidak hebat. Mula -mula pastikan sistem telah dikemas kini ke patch terkini, kemudian muat turun pakej pemasangan kod VS yang sepadan dengan seni bina sistem dan pasangnya seperti yang diminta. Selepas pemasangan, sedar bahawa beberapa sambungan mungkin tidak sesuai dengan Windows 8 dan perlu mencari sambungan alternatif atau menggunakan sistem Windows yang lebih baru dalam mesin maya. Pasang sambungan yang diperlukan untuk memeriksa sama ada ia berfungsi dengan betul. Walaupun kod VS boleh dilaksanakan pada Windows 8, disyorkan untuk menaik taraf ke sistem Windows yang lebih baru untuk pengalaman dan keselamatan pembangunan yang lebih baik.

PHP dan Python: menyelam mendalam ke dalam sejarah mereka PHP dan Python: menyelam mendalam ke dalam sejarah mereka Apr 18, 2025 am 12:25 AM

PHP berasal pada tahun 1994 dan dibangunkan oleh Rasmuslerdorf. Ia pada asalnya digunakan untuk mengesan pelawat laman web dan secara beransur-ansur berkembang menjadi bahasa skrip sisi pelayan dan digunakan secara meluas dalam pembangunan web. Python telah dibangunkan oleh Guidovan Rossum pada akhir 1980 -an dan pertama kali dikeluarkan pada tahun 1991. Ia menekankan kebolehbacaan dan kesederhanaan kod, dan sesuai untuk pengkomputeran saintifik, analisis data dan bidang lain.

Cara menjalankan program di terminal vscode Cara menjalankan program di terminal vscode Apr 15, 2025 pm 06:42 PM

Dalam kod VS, anda boleh menjalankan program di terminal melalui langkah -langkah berikut: Sediakan kod dan buka terminal bersepadu untuk memastikan bahawa direktori kod selaras dengan direktori kerja terminal. Pilih arahan Run mengikut bahasa pengaturcaraan (seperti python python your_file_name.py) untuk memeriksa sama ada ia berjalan dengan jayanya dan menyelesaikan kesilapan. Gunakan debugger untuk meningkatkan kecekapan debug.

See all articles