Python 与 perl 排序性能

标签 python performance perl sorting

解决方案

这解决了我的 Perl 代码的所有问题(加上额外的实现代码....:-))总之,Perl 和 Python 都同样出色。

use WWW::Curl::Easy;

感谢所有回复的人,非常感谢。

编辑

看来我正在使用的 Perl 代码大部分时间都在执行 http get,例如:

my $start_time = gettimeofday;
$request = HTTP::Request->new('GET', 'http://localhost:8080/data.json');
$response = $ua->request($request);
$page = $response->content;
my $end_time = gettimeofday;
print "Time taken @{[ $end_time - $start_time ]} seconds.\n";

结果是:

Time taken 74.2324419021606 seconds.

我的 python 代码比较:

start = time.time()
r = requests.get('http://localhost:8080/data.json', timeout=120, stream=False)

maxsize = 100000000
content = ''
for chunk in r.iter_content(2048):
    content += chunk
    if len(content) > maxsize:
        r.close()
        raise ValueError('Response too large')

end = time.time()
timetaken = end-start
print timetaken

结果是:

20.3471381664

在这两种情况下,排序时间都是亚秒级的。所以首先我为这个误导性的问题道歉,这是我永远不要做出假设的另一个教训....:-)

我不确定现在如何处理这个问题最好。也许有人可以提出用 perl 执行请求的更好方法?

编辑结束

这只是一个关于 Perl 与 Python 排序性能差异的快速问题。这不是关于哪种语言更好/更快等的问题,为了记录,我首先用 perl 编写这个,注意到排序所花费的时间,然后尝试用 python 编写相同的东西以查看它有多快.我只是想知道,如何让 perl 代码的执行速度与 python 代码一样快?

假设我们有以下 json:

["3434343424335": {
        "key1": 2322,
        "key2": 88232,
        "key3": 83844,
        "key4": 444454,
        "key5": 34343543,
        "key6": 2323232
    },
"78237236343434": {
        "key1": 23676722,
        "key2": 856568232,
        "key3": 838723244,
        "key4": 4434544454,
        "key5": 3432323543,
        "key6": 2323232
    }
]

假设我们有一个包含大约 30k-40k 条记录的列表,我们希望通过其中一个子键对其进行排序。然后我们想要构建一个新的记录数组,该数组由子键排序。

Perl - 大约需要 27 秒

my @list;
$decoded = decode_json($page);
foreach my $id (sort {$decoded->{$b}->{key5} <=> $decoded->{$a}->{key5}} keys %{$decoded}) {
    push(@list,{"key"=>$id,"key1"=>$decoded->{$id}{key1}...etc));
}

Python - 大约需要 6 秒

list = []
data = json.loads(content)
data2 = sorted(data, key = lambda x: data[x]['key5'], reverse=True)

for key in data2:
     tmp= {'id':key,'key1':data[key]['key1'],etc.....}
     list.append(tmp)

对于 perl 代码,我尝试使用以下调整:

use sort '_quicksort';  # use a quicksort algorithm
use sort '_mergesort';  # use a mergesort algorithm

最佳答案

您的基准测试存在缺陷,您正在对多个变量而不是一个变量进行基准测试。它不仅对数据进行排序,还进行 JSON 解码、创建字符串以及附加到数组。您无法知道有多少时间花在整理上,又有多少时间花在做其他事情上。

更糟糕的是,Perl 中有几种不同的 JSON 实现,每一种都有自己不同的性能特征。更改底层 JSON 库,基准将再次更改。

如果您想要基准排序,则必须更改基准代码以消除从基准(无论是否为 JSON)加载测试数据的成本。

Perl 和 Python 有自己的内部基准测试库,可以对单个函数进行基准测试,但它们的工具可能使它们的性能远不如现实世界中的性能。每个基准测试实现的性能拖累都会不同,并且可能会引入错误的偏见。这些基准测试库对于比较同一程序中的两个函数更有用。对于语言之间的比较,请保持简单。

要获得准确的基准,最简单的方法是使用挂钟在程序中为它们计时。

# The current time to the microsecond.
use Time::HiRes qw(gettimeofday);

my @list;
my $decoded = decode_json($page);

my $start_time = gettimeofday;

foreach my $id (sort {$decoded->{$b}->{key5} <=> $decoded->{$a}->{key5}} keys %{$decoded}) {
    push(@list,{"key"=>$id,"key1"=>$decoded->{$id}{key1}...etc));
}

my $end_time = gettimeofday;

print "sort and append took @{[ $end_time - $start_time ]} seconds\n";

(我将 Python 版本留作练习)

从这里您可以提高您的技术。您可以使用 CPU 秒而不是挂钟。数组附加和创建字符串的成本仍然包含在基准测试中,它们可以被消除,所以你只是基准测试排序。等等。

此外,您可以使用 a profiler找出您的程序将时间花在哪里。这些与基准测试库具有相同的原始性能警告,结果仅对找出程序在何处使用的时间百分比有用,但事实证明,它对于快速查看基准测试是否有意外拖累很有用。

重要的是对您认为的基准进行基准测试。

关于Python 与 perl 排序性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31752670/

相关文章:

python - 为什么 int numpy 数组的逆幂为 0,尽管 "from __future__ import division"?

sql - 从SQL Server全文索引中获取前n个最新条目

performance - “retired”是什么意思?

perl - 如何获取使用DBI插入的最后一行?

html - 正则表达式根据其他列获取列信息

python - 用另一列的值替换二进制列中的值

python - 如何在 django admn 中插入后获取记录 ID?

SQL 查询在 Symfony 中非常慢,但在 PhpMyAdmin 中非常快

perl - 获取两个 UNIX 时间戳之间的日变化点

python - MySQL 中的数字序列