Python 编程中字符串插入最快的方式介绍

在 MapReduce 分布式计算时有这样一种场景:mapper 输入来自多个不同的数据源,共同点是每行记录第一列是作为 key 的 id 列,reducer 需要根据数据源的不同,进行相应的处理。由于数据到 reducer 阶段已经无法区分来自什么文件,所以一般采取的方法是 mapper 为数据记录打一个 TAG。为了便于使用,我习惯于把这个 TAG 打到数据的第二列(第一列为 id 列,作为 reduce/join 的 key),所以有这样的 mapper 函数:

def mapper1(line):
    l = line.split('t', 1)
    return "%st%st%s" % (l[0], 'TAG', l[1])

这样给定输入:

s = "3001    VALUE"

mapper1(s) 的结果就是:

s = "3001    TAG    VALUE"

这是一个潜意识就想到的很直白的函数,但是我今天忽然脑子转筋,陷入了“这是最快的吗”思维怪圈里。于是我就想,还有什么其它方法呢?哦,格式化的表达式可以用 string 的 + 运算来表示:

def mapper2(line):
    l = line.split('t', 1)
    return l[0] + 't' + 'TAG' + 't' + l[1]

上面是故意将 't' 分开写,因为一般 TAG 是以变量方式传入的。还有,都说 join 比 + 快,那么也可以这样:

def mapper3(line):
    l = line.split('t', 1)
    l.insert(1, 'TAG')
    return 't'.join(l)

split 可能要消耗额外的空间,那就换 find:

def mapper4(line):
    pos = line.find('t')
    return "%st%st%s" % (line[0:pos], 'TAG', line[pos+1:])

变态一点儿,第一个数是整数嘛,换成整型输出:

def mapper5(line):
    pos = line.find('t')
    pid = long(line[0:pos])
    return "%dt%st%s" % (pid, 'TAG', line[pos+1:])

再换个思路,split 可以换成 partition:

def mapper6(line):
    (h,s,t) = line.partition('t')
    return "%st%st%s" % (h, 'TAG', t)

或者干脆 ticky 一点儿,用 replace 替换第一个找到的制表符:

def mapper7(line):
    return line.replace('t', 't'+'TAG'+'t', 1)

哇,看一下,原来可选的方法还真不少,而且我相信这肯定没有列举到所有的方法。看到这里,就这几个有限的算法,你猜一下哪个最快?最快的比最慢的快多少?

先把计时方法贴一下:

for i in range(1,8):
    f = 'mapper%d(s)' % i
    su = "from __main__ import mapper%d,s" % i
    print f, ':', timeit.Timer(f, setup=su).timeit()

下面是答案:

mapper1(s) : 1.32489800453
mapper2(s) : 1.2933549881
mapper3(s) : 1.65229916573
mapper4(s) : 1.22059297562
mapper5(s) : 2.60358095169
mapper6(s) : 0.956777095795
mapper7(s) : 0.726199865341

最后胜出的是 mapper7 (tricky 的 replace 方法),最慢的是 mapper5 (蛋疼的 id 转数字方法),最慢的耗时是最慢的约 3.6 倍。最早想到的 mapper1 方法在 7 种方法中排名——第 5!耗时是最快方法的 1.8 倍。考虑到 mapper 足够简单,这个将近一倍的开销还是有一点点意义的。

时间: 2024-09-23 01:27:52

Python 编程中字符串插入最快的方式介绍的相关文章

Python编程中运用闭包时所需要注意的一些地方

  这篇文章主要介绍了Python编程中运用闭包时所需要注意的一些地方,文章来自国内知名的Python开发者felinx的博客,需要的朋友可以参考下 写下这篇博客,起源于Tornado邮件群组的这个问题how to use outer variable in inner method,这里面老外的回答很有参考价值,关键点基本都说到了.我在这里用一些有趣的例子来做些解析,简要的阐述下Python的闭包规则,首先看一个经典的例子: ? 1 2 3 4 5 6 7 8 9 10 11 def foo(

Python编程中的反模式实例分析_python

本文实例讲述了Python编程中的反模式.分享给大家供大家参考.具体分析如下: Python是时下最热门的编程语言之一了.简洁而富有表达力的语法,两三行代码往往就能解决十来行C代码才能解决的问题:丰富的标准库和第三方库,大大节约了开发时间,使它成为那些对性能没有严苛要求的开发任务的首选:强大而活跃的社区,齐全的文档,也使很多编程的初学者选择了它作为自己的第一门编程语言.甚至有国外的报道称,Python已经成为了美国顶尖大学里最受欢迎的编程入门教学语言. 要学好一门编程语言实属不易,在初学阶段,就

mybatis中批量插入的两种方式(高效插入)_java

MyBatis简介 MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录. 一.mybiats foreach标签 foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合.foreach元素的属性主

对于Python编程中一些重用与缩减的建议_python

返璞归真 许多流行的玩具都以这样一个概念为基础:简单的积木.这些简单的积木可通过多种方式组合在一起构造出全新的作品 -- 有时甚至完全令人出乎意料.这一概念同样适用于现实生活中的建筑领域,将基本原材料组合在一起,形成有用的建筑物.平凡无奇的材料.技术和工具简化了新建筑物的建造过程,同样也简化了对新踏入此领域的人员的培训. 相同的基本概念也适用于计算机程序开发技术,包括以 Python 编程语言编写的程序.本文介绍了使用 Python 创建基本构件 (building block) 的方法,可用于

Python编程中的反模式

问题描述 转自博客园:http://www.cnblogs.com/rrxc/p/4350201.htmlPython是时下最热门的编程语言之一了.简洁而富有表达力的语法,两三行代码往往就能解决十来行C代码才能解决的问题:丰富的标准库和第三方库,大大节约了开发时间,使它成为那些对性能没有严苛要求的开发任务的首选:强大而活跃的社区,齐全的文档,也使很多编程的初学者选择了它作为自己的第一门编程语言.甚至有国外的http://cacm.acm.org/blogs/blog ... ltext称,Pyt

Android编程中的5种数据存储方式_Android

本文介绍Android平台进行数据存储的五大方式,分别如下: 1 使用SharedPreferences存储数据 2 文件存储数据      3 SQLite数据库存储数据 4 使用ContentProvider存储数据 5 网络存储数据 下面详细讲解这五种方式的特点 第一种: 使用SharedPreferences存储数据 适用范围:保存少量的数据,且这些数据的格式非常简单:字符串型.基本类型的值.比如应用程序的各种配置信息(如是否打开音效.是否使用震动效果.小游戏的玩家积分等),解锁口 令密

在Python编程过程中用单元测试法调试代码的介绍_python

对于程序开发新手来说,一个最常见的困惑是测试的主题.他们隐约觉得"单元测试"是很好的,而且他们也应该做单元测试.但他们却不懂这个词的真正含义.如果这听起来像是在说你,不要怕!在这篇文章中,我将介绍什么是单元测试,为什么它有用,以及如何对Python的代码进行单元测试. 什么是测试? 在讨论为什么测试很有用.怎样进行测试之前,让我们先花几分钟来定义一下"单元测试"究竟是什么.在一般的编程术语中,"测试"指的是通过编写可以调用的代码(独立于你实际应用

Andriod开发中引入jar包的正确方式介绍

andriod中如果引入jar包的方式不对就会出现一些奇怪的错误. 工作的时候恰好有一个jar包需要调用,结果用了很长时间才解决出现的bug. 刚开始是这样引用的(eclipse): 右键工程,Build path,java build path, 选择libraries,在右边的按钮中点击"Add External JARs", 然后选择合适的jar包(大部分人应该会这样做). 结果控制台立刻报错:conversion to dalvik format failed with err

整理Java编程中字符串的常用操作方法_java

字符一般情况下,当我们处理字符时,我们用原始数据类型 char. 示例 char ch = 'a'; // Unicode for uppercase Greek omega character char uniChar = '\u039A'; // an array of chars char[] charArray ={ 'a', 'b', 'c', 'd', 'e' }; 然而在开发中,我们会遇到需要使用对象而不是原始数据类型的情况.为了达到这个需求.Java 为原始数据类型 char 提