gpt4 book ai didi

r - 在 R 中使用多线程/核心以压缩形式保存对象的方法是什么?

转载 作者:行者123 更新时间:2023-12-03 12:49:05 25 4
gpt4 key购买 nike

有许多压缩协议(protocol)支持多核/线程压缩/解压缩。然而,基本的解压/压缩方法似乎都使用单核(即使至少算法支持多核)。

如果没有现有工具可以完成此任务,是否有办法在不使用 Java 或 C 的情况下管理它?

我认为我可以使用管道序列化的能力,通过以某种方式将R对象传递到shell/命令行来获得我想要的东西。但是,我似乎无法以这种方式从 R 中获得对象的可用形式(也许我错过了一些东西?)。 “显而易见”的解决方案是使用 dput,但该函数帮助中的注释非常清楚地表明,使用 dput 将 R 对象转换为 ASCII 是为了保存对于dput来说不是一个合适(或安全)的目的。提到的替代方案 dump 的作用类似于 save (我宁愿使用 saveRDS 之类的东西),并且仍然将文件路由到 。如果不深入研究 R 的 C 代码,内部是难以理解的。

我应该考虑哪些其他方法来解决这个问题?

最佳答案

利用@Martin提供的资源,我编写了以下代码。

xz

对于压缩,我想先尝试使用 xz。然而,目前 Ubuntu 14.04 LTS 上打包的 xz 版本(5.1.0alpha)不支持并行压缩。所以,我用 pxz 代替。

saveRDS.xz <- function(object,file,threads=parallel::detectCores()) {
con <- pipe(paste0("pxz -T",threads," > ",file),"wb")
saveRDS(object, file = con, compress=FALSE)
close(con)
}

配套代码 readRDS.xz 代码也适用于使用 xz 压缩保存的任何常规 RDS 文件。另请注意,虽然 pxz 不会并行解压缩,但使用此代码可以节省时间(在我的系统上节省了大约 1/3)。这是因为解压缩转移到另一个线程,而 R 线程被留下来处理传入的流。在我的系统上,R 的单线程 CPU 使用率远远早于 pxz 达到最大值。

readRDS.xz <- function(file,threads=parallel::detectCores()) {
con <- pipe(paste0("pxz -d -k -c -T",threads," ",file))
object <- readRDS(file = con)
close(con)
return(object)
}

pig

或者我们可以使用pigz (gz)来压缩和解压缩。

saveRDS.gz <- function(object,file,threads=parallel::detectCores()) { con <- 管道(paste0("pigz -p",线程,">",文件),"wb") saveRDS(对象,文件= con) 关闭(反)}

pigz中的解压并不完全是多线程的。但与 xz 一样,从 R 线程中解压会带来速度优势。在我的系统上,pxz 和 Pigz 提供相似的解压时间(可能是由于上一节中提到的 R 瓶颈)。

saveRDS.gz <- function(object,file,threads=parallel::detectCores()) {
con <- pipe(paste0("pigz -p",threads," > ",file),"wb")
saveRDS(object, file = con)
close(con)
}

readRDS.gz <- function(file,threads=parallel::detectCores()) {
con <- pipe(paste0("pigz -d -c -p",threads," ",file))
object <- readRDS(file = con)
close(con)
return(object)
}

bzip2

为我提供的性能介于其他两者之间,因此我在这里跳过它。

在一起

建立这些函数后,我们可以编写一个快速包装器,以便它做正确的事情。

readRDS.p <- function(file,threads=parallel::detectCores()) {
#Hypothetically we could use initial bytes to determine file format, but here we use the Linux command file because the readBin implementation was not immediately obvious
fileDetails <- system2("file",args=file,stdout=TRUE)
selector <- sapply(c("gzip","XZ"),function (x) {grepl(x,fileDetails)})
format <- names(selector)[selector]
if (format == "gz") {
object <- readRDS.gz(file, threads=threads)
} else if (format == "XZ") {
object <- readRDS.xz(file, threads=threads)
} else {
object <- readRDS(file)
}
return(object)
}

关于r - 在 R 中使用多线程/核心以压缩形式保存对象的方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28927750/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com