【发布时间】:2021-11-13 14:05:12
【问题描述】:
您好,我不知道这是否是 SO 的合法问题。
但是我有一个脚本,用于根据标签将照片分类到文件夹中。它使用exifr 包来执行此操作。
但是,它的运行速度非常慢。我尝试使用guides 对其进行改进,但我所做的最终无法正常工作。是否有了解矢量化和/或优化的人可以提出一些建议。 谢谢!
#----- Imports ----
library(exifr)
# ---------- Functions ----------
'%!in%' <- function(x,y)!('%in%'(x,y))
tagcatcher <- function(dat){
tags <- c()
for (tagNameTry in keywords_names ) {
if (tagNameTry %in% names(dat)) {
xs <- dat[tagNameTry]
if (typeof(xs) == "list") {
xs <- xs[[1]]
l <- length(xs[[1]])
x <- c()
for (i in 1:l) {
x <- c(x,xs[[1]][i])
}
} else {
x <- xs
}
tags <- c(tags,x)
}
}
tags <- unique(tags)
return(tags)
}
# ----------- Settings ----------
ss <- "/"
haystacks <- c("H:MyPhotos")
organizedMediaPhotos <- "V:/Photos"
all_files <- list.files(haystacks,recursive = TRUE, full.names = TRUE)
keywords_names <- c("Category","XPKeywords","Keywords")
ctags <- list.dirs(organizedMediaPhotos)[list.dirs(organizedMediaPhotos) %!in% organizedMediaPhotos]
current_tags <- c()
for (ctag in ctags) {
x <- strsplit(ctag,"/")
x <- x[[1]]
x <- x[length(x)]
current_tags <- c(current_tags,x)
}
# Main Loop - That Needs to be faster
for (cur_file in all_files) {
print(cur_file)
cur_dat <- read_exif(cur_file,tags=keywords_names)
tags <- tagcatcher(cur_dat)
for (tag in tags) {
tag_folder <- paste(organizedMediaPhotos,ss,tag,sep="")
if (tag %!in% current_tags) {
dir.create(tag_folder)
print(paste("creating tag folder: ",tag_folder))
}
pic_path <- paste(tag_folder,ss,basename(cur_file),sep="")
if (!file.exists(pic_path)) {
file.copy(cur_file,pic_path)
print(paste("moved file from ",cur_file, " to ", pic_path))
}
}
}
【问题讨论】:
-
一个普遍的评论是你正在增长一个(可能非常大?)向量;这确实(不必要地)很慢。另一个不相关的评论:请不要将非语法变量名写成字符串。 R 允许这样做的事实是一个错误,只会导致混乱。相反,请按照documentation(在“名称和标识符”下)中的建议使用反引号。此外,您可以将
`%!in%`的定义缩短为`%!in%` = Negate(`%in%`)。 -
必须进行任何基准测试才能查看循环中的哪些步骤最慢?
-
必须是“read_exif(cur_file,tags=keywords_names)”
-
read_exif可以接受文件名向量。因此,如果调用函数有明显的开销,则将调用移到“处理当前文件”循环之外可能是有益的。
标签: r optimization tags vectorization photo