【发布时间】:2010-05-05 01:24:41
【问题描述】:
我有 4 个相当复杂的 r 脚本,用于操作 csv 和 xml 文件。这些是由他们专门在 r 中工作的另一个部门创建的。
我的理解是,虽然 r 在处理数据时非常快,但它并没有真正针对文件操作进行优化。我可以期望通过将这些脚本转换为 python 来显着提高速度吗?或者这是在浪费时间?
【问题讨论】:
标签: python file r performance
我有 4 个相当复杂的 r 脚本,用于操作 csv 和 xml 文件。这些是由他们专门在 r 中工作的另一个部门创建的。
我的理解是,虽然 r 在处理数据时非常快,但它并没有真正针对文件操作进行优化。我可以期望通过将这些脚本转换为 python 来显着提高速度吗?或者这是在浪费时间?
【问题讨论】:
标签: python file r performance
我经常使用 R 和 Python 编写代码。我发现用于编写、读取和解析信息的 Python 模块更易于使用、维护和更新。像 python 这样的小细节可以让你处理 R 索引上的项目列表,使事情更容易阅读。
我非常怀疑您是否会通过切换语言获得任何显着的加速。如果您正在成为这些脚本的新“维护者”并且发现 Python 更易于理解和扩展,那么我会说去吧。
计算机时间很便宜……程序员的时间很贵。如果你还有其他事情要做,那么我会带着你所拥有的东西一瘸一拐地走,直到你有空闲的时间和他们一起玩。
希望对您有所帮助。
【讨论】:
几周前,我编写了一个 Python 脚本,用于从大型 (280 MB) CSV file 中提取一些行。更准确地说,我想提取 dbpedia 中具有 ISIN 字段的公司的所有可用信息。后来我在 R 中尝试了同样的方法,但尽我所能,R 脚本比 python 脚本多 10 倍(在我相当旧的笔记本电脑上是 10 分钟对 1 分钟)。也许这是由于我对 R 的了解,在这种情况下,我将不胜感激有关如何使脚本更快的任何提示。这是python代码
from time import clock
clock()
infile = "infobox_de.csv"
outfile = "companies.csv"
reader = open(infile, "rb")
writer = open(outfile, "w")
oldthing = ""
isCompany = False
hasISIN = False
matches = 0
for line in reader:
row = line.strip().split("\t")
if len(row)>0: thing = row[0]
if len(row)>1: key = row[1]
if len(row)>2: value = row[2]
if (len(row)>0) and (oldthing != thing):
if isCompany and hasISIN:
matches += 1
for tup in buf:
writer.write(tup)
buf = []
isCompany = False
hasISIN = False
isCompany = isCompany or ((key.lower()=="wikipageusestemplate") and (value.lower()=="template:infobox_unternehmen"))
hasISIN = hasISIN or ((key.lower()=="isin") and (value!=""))
oldthing = thing
buf.append(line)
writer.close()
print "finished after ", clock(), " seconds; ", matches, " matches."
这里是 R 脚本(我没有等效版本了,但是一个非常相似的版本,它返回一个数据帧而不是编写一个 csv 文件并且不检查 ISIN):
infile <- "infobox_de.csv"
maxLines=65000
reader <- file(infile, "r")
writer <- textConnection("queryRes", open = "w", local = TRUE)
writeLines("thing\tkey\tvalue\tetc\n", writer)
oldthing <- ""
hasInfobox <- FALSE
lineNumber <- 0
matches <- 0
key <- ""
thing <- ""
repeat {
lines <- readLines(reader, maxLines)
if (length(lines)==0) break
for (line in lines) {
lineNumber <- lineNumber + 1
row = unlist(strsplit(line, "\t"))
if (length(row)>0) thing <- row[1]
if (length(row)>1) key <- row[2]
if (length(row)>2) value <- row[3]
if ((length(row)>0) && (oldthing != thing)) {
if (hasInfobox) {
matches <- matches + 1
writeLines(buf, writer)
}
buf <- c()
hasInfobox <- FALSE
}
hasInfobox <- hasInfobox || ((tolower(key)=="wikipageusestemplate") && (tolower(value)==tolower("template:infobox_unternehmen")))
oldthing <- thing
buf <- c(buf, line)
}
}
close(reader)
close(writer)
readRes <- textConnection(queryRes, "r")
result <- read.csv(readRes, sep="\t", stringsAsFactors=FALSE)
close(readRes)
result
我明确所做的是将 readLines 限制为最多 65000 行。我这样做是因为我认为我的 500MB RAM 机器会内存不足。我没有尝试没有这个限制。
【讨论】:
知道时间花在了哪里。如果您的 R 脚本在磁盘 IO 上遇到瓶颈(在这种情况下很有可能),那么您可以在手动优化的程序集中重写它们并且不会更快。与优化一样,如果您不首先进行测量,那么您只会随风而去。如果它们在磁盘 IO 上没有瓶颈,您可能会看到改进算法比更改语言带来更多好处。
【讨论】:
“文件操作”是什么意思?您是在谈论移动文件,删除,复制等吗?在这种情况下,如果您正在谈论读取数据,执行计算,也许写出一个新文件,我会使用 shell,例如 bash 等等,那么您可能会使用 Python 或 R。除非维护是一个问题,否则我会将其保留为 R 并找到其他要炸的鱼,因为您不会看到足够的加速来证明您的时间和精力是合理的在移植该代码。
【讨论】:
我的猜测是,您可能不会及时看到太多的加速。在比较高级语言时,语言的开销通常不是性能问题的罪魁祸首。通常,问题在于您的算法。
我对 R 不是很熟悉,但是你可能会发现通过一次将较大的数据块读取到内存中而不是较小的块(更少的系统调用)来加快速度。如果 R 没有能力改变这样的东西,你可能会发现 python 可以仅仅因为这个能力而变得更快。
【讨论】:
R 数据操作具有快速的规则。基础是:
搜索 R 时间优化和分析,您会发现很多资源可以帮助您。
【讨论】: