为什么这个程序在 Python 中比 Objective-C 更快?

2024-02-27

我感兴趣了这个小例子 https://stackoverflow.com/questions/5523058/how-to-optimize-this-python-code-from-thinkpython-exercise-10-10/5523071#comment-6276679Python 中循环遍历大型单词列表的算法。我正在编写一些“工具”,允许我以与 Python 类似的方式对 Objective-C 字符串或数组进行切片。

具体来说,这个优雅的解决方案 https://stackoverflow.com/questions/5523058/how-to-optimize-this-python-code-from-thinkpython-exercise-10-10/5523071#5523071因其执行速度非常快而引起了我的注意,它使用字符串切片作为算法的关键元素。尝试在不切片的情况下解决这个问题!

我已经使用复制了我的本地版本莫比单词表 http://icon.shef.ac.uk/Moby/以下。您可以使用/usr/share/dict/words如果您不想下载 Moby。来源只是一个类似于字典的大型独特单词列表。

#!/usr/bin/env python

count=0
words = set(line.strip() for line in   
           open("/Users/andrew/Downloads/Moby/mwords/354984si.ngl"))
for w in words:
    even, odd = w[::2], w[1::2]
    if even in words and odd in words:
        count+=1

print count      

该脚本将 a) 由 Python 解释; b) 读取 4.1 MB、354,983 字的 Moby 词典文件; c) 剥线; d) 将线路放入一组; e) 找到给定单词的偶数和奇数也是单词的所有组合。在 MacBook Pro 上执行大约需要 0.73 秒。

我尝试用 Objective-C 重写相同的程序。我是这门语言的初学者,所以请放轻松,但请指出错误。

#import <Foundation/Foundation.h>

NSString *sliceString(NSString *inString, NSUInteger start, NSUInteger stop, 
        NSUInteger step){
    NSUInteger strLength = [inString length];

    if(stop > strLength) {
        stop = strLength;
    }

    if(start > strLength) {
        start = strLength;
    }

    NSUInteger capacity = (stop-start)/step;
    NSMutableString *rtr=[NSMutableString stringWithCapacity:capacity];    

    for(NSUInteger i=start; i < stop; i+=step){
        [rtr appendFormat:@"%c",[inString characterAtIndex:i]];
    }
    return rtr;
}

NSSet * getDictWords(NSString *path){

    NSError *error = nil;
    NSString *words = [[NSString alloc] initWithContentsOfFile:path
                         encoding:NSUTF8StringEncoding error:&error];
    NSCharacterSet *sep=[NSCharacterSet newlineCharacterSet];
    NSPredicate *noEmptyStrings = 
                     [NSPredicate predicateWithFormat:@"SELF != ''"];

    if (words == nil) {
        // deal with error ...
    }
    // ...

    NSArray *temp=[words componentsSeparatedByCharactersInSet:sep];
    NSArray *lines = 
        [temp filteredArrayUsingPredicate:noEmptyStrings];

    NSSet *rtr=[NSSet setWithArray:lines];

    NSLog(@"lines: %lul, word set: %lul",[lines count],[rtr count]);
    [words release];

    return rtr;    
}

int main (int argc, const char * argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    int count=0;

    NSSet *dict = 
       getDictWords(@"/Users/andrew/Downloads/Moby/mwords/354984si.ngl");

    NSLog(@"Start");

    for(NSString *element in dict){
        NSString *odd_char=sliceString(element, 1,[element length], 2);
        NSString *even_char=sliceString(element, 0, [element length], 2);
        if([dict member:even_char] && [dict member:odd_char]){
            count++;
        }

    }    
    NSLog(@"count=%i",count);

    [pool drain];
    return 0;
}

Objective-C 版本产生相同的结果(13,341 个单词),但花费了近 3 秒的时间。我一定是做了一些严重错误,编译语言比脚本语言慢了 3 倍以上,但如果我能明白为什么,我就该死了。

基本算法是相同的:读取行,剥离它们,然后将它们放入一个集合中。

我猜测缓慢的是 NSString 元素的处理,但我不知道替代方案。

Edit

我将Python编辑为:

#!/usr/bin/env python
import codecs
count=0
words = set(line.strip() for line in 
     codecs.open("/Users/andrew/Downloads/Moby/mwords/354984si.ngl",
          encoding='utf-8'))
for w in words:
    if w[::2] in words and w[1::2] in words:
        count+=1

print count 

为了使 utf-8 与 utf-8 NSString 在同一平面上。这使 Python 的速度减慢至 1.9 秒。

我还将切片测试切换为短路类型建议 https://stackoverflow.com/questions/5616847/why-is-this-program-faster-in-python-than-objective-c/5617487#5617487对于 Python 和 obj-c 版本。现在他们的速度已经接近了。我还尝试使用 C 数组而不是 NSString,这更快,但没那么容易。这样做也会失去对 utf-8 的支持。

Python 真的很酷...

Edit 2

我发现了一个瓶颈,大大加快了速度。而不是使用[rtr appendFormat:@"%c",[inString characterAtIndex:i]];方法将字符附加到返回字符串,我使用了这个:

for(NSUInteger i=start; i < stop; i+=step){
    buf[0]=[inString characterAtIndex:i];
    [rtr appendString:[NSString stringWithCharacters:buf length:1]];
}

现在我能finally声称 Objective-C 版本比 Python 版本快——但快不了多少。


请记住,Python 版本的编写目的是将在 CPython 上执行时的大量繁重工作移至高度优化的 C 代码中(特别是文件输入缓冲、字符串切片和哈希表查找,以检查是否even and odd are in words).

也就是说,您似乎在 Objective-C 代码中将文件解码为 UTF-8,但在 Python 代码中保留二进制文件。在 Objective-C 版本中使用 Unicode NSString,但在 Python 版本中使用 8 位字节字符串并不是一个真正公平的比较 - 如果您使用,我预计 Python 版本的性能会显着下降codecs.open()以声明的编码打开文件"utf-8".

您还进行了完整的第二遍来去除 Objective-C 中的空行,而 Python 代码中不存在这样的步骤。

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

为什么这个程序在 Python 中比 Objective-C 更快? 的相关文章

  • 导入错误:没有名为 _ssl 的模块

    带 Python 2 7 的 Ubuntu Maverick 我不知道如何解决以下导入错误 gt gt gt import ssl Traceback most recent call last File
  • 如何在 Sublime Text 2 的 OSX 终端中显示构建结果

    我刚刚从 TextMate 切换到 Sublime Text 2 我非常喜欢它 让我困扰的一件事是默认的构建结果显示在 ST2 的底部 我的程序产生一些很长的结果 显示它的理想方式 如在 TM2 中 是并排查看它们 如何在 Mac 操作系统
  • 如何在Windows上模拟socket.socketpair

    标准Python函数套接字 套接字对 https docs python org 3 library socket html socket socketpair不幸的是 它在 Windows 上不可用 从 Python 3 4 1 开始 我
  • 安装后 Anaconda 提示损坏

    我刚刚安装张量流GPU创建单独的后环境按照以下指示here https github com antoniosehk keras tensorflow windows installation 但是 安装后当我关闭提示窗口并打开新航站楼弹出
  • keras加载模型错误尝试将包含17层的权重文件加载到0层的模型中

    我目前正在使用 keras 开发 vgg16 模型 我用我的一些图层微调 vgg 模型 拟合我的模型 训练 后 我保存我的模型model save name h5 可以毫无问题地保存 但是 当我尝试使用以下命令重新加载模型时load mod
  • NameError:名称“urllib”未定义”

    CODE import networkx as net from urllib request import urlopen def read lj friends g name fetch the friend list from Liv
  • python pandas 中的双端队列

    我正在使用Python的deque 实现一个简单的循环缓冲区 from collections import deque import numpy as np test sequence np array range 100 2 resha
  • 在 Objective C 的类方法中引用类本身

    我希望我没有跳过 ObjC 手册中的这一部分 但是是否可以从类的一个类方法中引用该类 就像在 PHP 中一样 您将使用 this 来引用当前实例 而 self 引用实例的类 this 的 ObjC 等价物将是 self 那么 PHP 的 s
  • Python:尝试检查有效的电话号码

    我正在尝试编写一个接受以下格式的电话号码的程序XXX XXX XXXX并将条目中的任何字母翻译为其相应的数字 现在我有了这个 如果启动不正确 它将允许您重新输入正确的数字 然后它会翻译输入的原始数字 我该如何解决 def main phon
  • Python - 按月对日期进行分组

    这是一个简单的问题 起初我认为很简单而忽略了它 一个小时过去了 我不太确定 所以 我有一个Python列表datetime对象 我想用图表来表示它们 x 值是年份和月份 y 值是此列表中本月发生的日期对象的数量 也许一个例子可以更好地证明这
  • 如何改变Python中特定打印字母的颜色?

    我正在尝试做一个简短的测验 并且想将错误答案显示为红色 欢迎来到我的测验 您想开始吗 是的 祝你好运 法国的首都是哪里 法国 随机答案不正确的答案 我正在尝试将其显示为红色 我的代码是 print Welcome to my Quiz be
  • Python 3 中“map”类型的对象没有 len()

    我在使用 Python 3 时遇到问题 我得到了 Python 2 7 代码 目前我正在尝试更新它 我收到错误 类型错误 map 类型的对象没有 len 在这部分 str len seed candidates 在我像这样初始化它之前 se
  • 在Python中重置生成器对象

    我有一个由多个yield 返回的生成器对象 准备调用该生成器是相当耗时的操作 这就是为什么我想多次重复使用生成器 y FunctionWithYield for x in y print x here must be something t
  • Python:计算字典的重复值

    我有一本字典如下 dictA unit1 test1 alpha unit1 test2 beta unit2 test1 alpha unit2 test2 gamma unit3 test1 delta unit3 test2 gamm
  • 检查所有值是否作为字典中的键存在

    我有一个值列表和一本字典 我想确保列表中的每个值都作为字典中的键存在 目前我正在使用两组来确定字典中是否存在任何值 unmapped set foo set bar keys 有没有更Pythonic的方法来测试这个 感觉有点像黑客 您的方
  • UIImageJPEGRepresentation 在视网膜显示屏上提供 2x 图像

    我有这段代码 它创建一个图像 然后向其添加一些效果并缩小其大小以使其largeThumbnail UIImage originalImage UIImage imageWithData self originalImage thumbnai
  • PFQueryTableViewController 错误

    我正在遵循在线教程 使用 Parse 作为后端创建照片共享应用程序 我已经运行了两次教程 两次都从头开始创建应用程序 但在同一位置仍然出现相同的错误 我到处寻找解决方案 但仍然没有运气 我正在使用 PFQueryTableViewContr
  • 您可以在 Python 类型注释中指定方差吗?

    你能发现下面代码中的错误吗 米皮不能 from typing import Dict Any def add items d Dict str Any gt None d foo 5 d Dict str str add items d f
  • 在 UIScrollview 上显示缩略图的最佳方法是什么(从服务器下载)

    我想在 UIScrollview 如照片应用程序 上显示许多图像 作为缩略图 所有图像将从服务器下载 据我所知 有几种选择 1 通过创建 UIImageviews 然后将它们添加为主滚动视图上的子视图 2 通过子类化一个UIView类 然后
  • Pandas 与 Numpy 数据帧

    看这几行代码 df2 df copy df2 1 df 1 df 1 values 1 df2 ix 0 0 我们的教练说我们需要使用 values属性来访问底层的 numpy 数组 否则我们的代码将无法工作 我知道 pandas Data

随机推荐

  • 更改 ggplot2 中栅格图的颜色

    由于一些不相关的原因 我尝试使用 ggplot2 而不是栅格包绘图函数来制作栅格图 我想缩放颜色 使图上的最低温度为蓝色 图上的最高温度为红色 而中间范围为白色 我已经尝试了 ggplot2 中的许多功能 但始终未能获得所需的结果 这就是我
  • 在 doxygen 中使用模块组内的节

    我寻求构建 doxygen 模块组内容的首选方法 例如 我想在不同部分的以下模块组中构造 details 文本 特别是每个部分都应该出现在生成的 PDF 的书签中 作为模块组的子元素 defgroup lorem brief Lorem i
  • 如何访问 Django Rest Framework 3.0 序列化程序中的查询参数?

    例如 在 Django Rest Framework 2 x 中 您可以访问序列化器中的 fields 查询参数 如下所示 fields self context request QUERY PARAMS get fields 这在 DRF
  • 如何针对 SharePoint 网站中的任何更改创建每日摘要警报

    我最近收到一个要求 要求某人接收有关 SharePoint 网站内任何更改的每日摘要警报 每个网站都有一个负责其网站内容的所有者 目前我们的工作方式是为站点内的每个列表 库自动设置警报 Get the Lists on this Site
  • PHP 有损/无损压缩图像

    我如何使用 PHP 以有损 无损压缩的方式压缩图像 就像这两个网站压缩图像一样 https compressor io https compressor io and https kraken io web interface https
  • Ruby 1.8.6 Array#uniq 不删除重复的哈希值

    我在 ruby 1 8 6 控制台中有这个数组 arr foo gt bar foo gt bar 两个元素彼此相等 arr 0 arr 1 gt true just in case there s some vs oddness arr
  • 如何解决此脚本中的 IE ClearType + jQuery 不透明度问题?

    我遇到了一个相当常见的问题 或者看起来是这样 经过一番谷歌搜索后 IE 在使用 jQuery 动画不透明度时会弄乱粗体文本和透明 png 您可以在此处查看示例 http dev gentlecode net dotme index samp
  • 从 Photoshop 动作到 Photoshop 脚本?

    我希望 Photoshop 自动为给定文件夹执行以下任务 加载给定文件夹中的所有 PNG 文件 将每个文件的模式转换为RGB color 为每个文件添加一层 将文件另存为 PSD 并放在同一文件夹中 有人告诉我这可以通过 Photoshop
  • R 创建带有 R CMD 检查的参考手册

    我正在编写一个 R 包 并希望制作该包中所有函数的 pdf 参考手册 我从here http grokbase com p r r devel 124dzqqxhg rd creating a reference manual during
  • Woocommerce 3 中无需在线支付交易的订单的 Google 分析集成

    我正在尝试在 Google 分析中添加有关订单的信息 但统计中并没有显示订单的接收信息 该网站不使用在线支付 或许原因与此有关 我用的是answer https stackoverflow com questions 52174961 go
  • Passport JS 中的 req.isAuthenticated() 是如何实现的? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 在passportJS文档中 我认为passportisAuthenticated功能没有很好地记录 How is req isAut
  • 在 .NET Core MVC 应用程序中使用 TempData 时出现错误 500

    你好 我正在尝试添加一个对象TempData并重定向到另一个控制器操作 我在使用时收到错误消息 500TempData public IActionResult Attach long Id Story searchedStory this
  • 固定div与滚动条重叠

    我在使用滚动条将固定 div 放置在其他 div 中时遇到问题 它与滚动条重叠 它发生在 safari 和 ie 11 下 当我将 z index 设置为低于带有滚动条的 div 时 固定 div 位于其下方 并且它会丢失交互 您无法单击链
  • Json.net 不再在重复的情况下抛出异常

    我正在尝试将我的 C 应用程序从 Newtonsoft JSON 6 升级到最新版本 9 0 1 我注意到反序列化包含重复元素的对象时行为发生了变化 例如 name test data myElem 1 myElem 2 当反序列化此类对象
  • 如何测试片段视图对用户是否可见?

    我有一个ViewPager 每个页面都是一个Fragment视图 我想测试片段是否位于可见区域 Fragment isVisible 唯一的测试 该片段附加到一个活动 片段设置为可见 该片段已添加到视图中 ViewPager 将创建 3 个
  • Airflow DAG动态结构

    我正在寻找一个可以决定 dag 结构的解决方案当 dag 被触发时因为我不确定我必须运行的操作员数量 请参阅下面我计划创建的执行顺序 Task B 1 Task C 1 Task B 2 Task C 2 Task A Task B 3 g
  • 您将如何制定每日课程表?

    我想做的事情非常简单 但我正在努力找到最好或最优雅的方法来做到这一点 我现在正在构建的 Rails 应用程序将有一个每日课程表 对于每个类别 与此问题相关的字段是 一周中的天 起始时间 结束时间 单个条目可能是这样的 星期几 星期三 开始时
  • 在php中显示html文件的内容[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 大家好 我
  • 如何解决“TypeError:callback.apply不是函数”?

    我正在做一个大学项目 我已经阅读了关于我的问题的每一篇文章 但我还没有找到解决方案 也许你可以帮我 代码如下 viewerObj update id currentIDViewerVar minutesWatched 5 upsert tr
  • 为什么这个程序在 Python 中比 Objective-C 更快?

    我感兴趣了这个小例子 https stackoverflow com questions 5523058 how to optimize this python code from thinkpython exercise 10 10 55