【发布时间】:2020-04-14 16:48:29
【问题描述】:
我编写的用于与 BaseX XML 数据库通信的包(请参阅https://CRAN.R-project.org/package=RBaseX)似乎很稳定,上个月我没有看到任何错误。唯一的问题是性能。 执行此查询:
let $words := for $text in collection('IncidentRemarks/IncidentRemarks.csv')/csv/record/INC_RM
return ft:tokenize($text)
return $words
大约需要 48 毫秒。从套接字读取生成的 350000 字节需要 > 100 秒。
我使用这个函数从套接字读取:
str_receive = function(input, output, bin = FALSE) {
if (missing(input)) input <- self$get_socket()
if (missing(output)) output <- raw(0)
while ((rd <- readBin(input, what = "raw", n =1)) > 0) {
if (rd == 0xff) rd <- readBin(input, what = "raw", n =1)
output <- c(output, rd)
}
# The 'Full'-method embeds a \0 in the output
if (!bin) ret <- strip_CR_NUL(output) %>% rawToChar()
else ret <- output
return(ret)
}
该软件包使用 R6。由于我还没有找到分析 R6 方法的好方法,所以我使用 browser() 进行调试。它表明while循环导致延迟。 (我猜想尤其是output <- c(output, rd) 是主要问题)。
加快从套接字读取的最佳方法是什么?
这个包的最新源代码可以在https://github.com/BenEngbers/RBaseX找到
本
PS。请不要告诉我必须使用“C”或“CPP”。我一直成功地避免使用这些语言 ;-)
4 月 6 日,
我隔离了从套接字读取的代码:
socket_reader <- function(socket_in) {
string_read <- raw(0)
while ((rd <- readBin(socket_in, what = "raw", n =1)) > 0) {
if (rd == 0xff) rd <- readBin(socket_in, what = "raw", n =1)
string_read <- c(string_read, rd)
}
return(string_read)
}
并将该代码替换为:
socket_reader <- function(socket_in) {
string_read <- raw(0)
CONT <- TRUE
Buf_Size <- 4096
while (CONT) {
read_buffer <- readBin(socket_in, what = "raw", n = Buf_Size)
if (length(read_buffer) < Buf_Size) CONT <- FALSE
string_read <- c(string_read, read_buffer)
}
string_read <- strip_FF(string_read)
string_read <- string_read[-(length(string_read))] %>% as.raw()
return(string_read)
}
这段代码应该快很多。 strip_FF() 函数从 string_read 中删除 (the) \0xFF 字节,因此两个版本应该给出相同的结果。
然而,在几个读取操作之间,我必须从连接中读取一个 (1) 状态字节。 \0x00 表示成功,\0x01 表示失败。
我的新版本无法读取该状态字节。
如何从连接中读取 1 个字节并移动连接中的位置?
本
【问题讨论】: