Есть ли что-нибудь быстрее readLines в R - ИЛИ как мне узнать, почему чтение моего соединения происходит так медленно? - PullRequest
0 голосов
/ 04 февраля 2019

У меня есть сокетное соединение между c (клиент) и R (R действует как сервер .. используя RStudio).C отправляет строку из 5 чисел в R. Например:

1 16.29 3.8 0 0

В RI я получаю строку, используя:

    con <- socketConnection(host="localhost", port = 8080, blocking=TRUE,
                        server=TRUE, open="r+")

, а следующая строка:

helloTall <- readLines(con,1)

Строки читаются нормально, но проблема в том, что мне приходится делать это очень часто (это упражнение на соединение с шагом по времени, и поэтому я должен делать это> 1000 раз, а в некоторых случаях более 500 000 раз),

readLines чрезвычайно медленны для этого типа работы, и readChar ничуть не лучше.Есть ли другой (намного) более быстрый способ прочитать приведенную выше короткую строку из соединения?

Я использую R 3.5.2.

ОБНОВЛЕНИЕ: Учитывая, что ответа пока нет,еще пара очков.Есть ли быстрый способ прочитать 5 цифр из сокета?Насколько я понимаю, они идут как строка.readLines занимает 1 минуту, чтобы прочитать эти 5 чисел, поэтому с> 5000 временных шагов в моем случае мне понадобится> 5000 минут !!!

ОБНОВЛЕНИЕ 2: Теперь я также попытался «отсканировать» содержимоесоединение и оно одинаково медленное:

hello2<-scan(con, sep=" ")

Это также занимает минуту, чтобы прочитать эти 5 чисел.Означает ли это, что con имеет много нулей или пробелов или что-то, что замедляет чтение его содержимого?Я почти ничего не знаю о связях.

Следуя запросу одного из комментариев, я также публикую код c, который в данном случае является клиентом (обратите внимание, что код c в моем случае вызывается из программы на языке Fortran):

// Client side C/C++ program to demonstrate Socket programming 
#include <stdio.h> 
#include <sys/socket.h> 
#include <stdlib.h> 
#include <netinet/in.h> 
#include <string.h> 
#include <stdint.h>
#define PORT 8080 


/*int main(int argc, char const *argv[]) */
void client_(int *nsinc, double *rTairExch, double *rToutExch, double *rTsolExch, double *ResTair) 
{ 
    struct sockaddr_in address; 
    int sock = 0, valread; 
    struct sockaddr_in serv_addr; 
    int itimensinc = *nsinc;
    double NoBitrTairExch=*rTairExch;
    double NoBitrToutExch=*rToutExch;
    double NoBitrTsolExch=*rTsolExch;
    double NoBitResTair=*ResTair;
    double length = snprintf( NULL, 0, \
                   "%d %.4g %.4g %.4g %.4g", itimensinc,NoBitrTairExch,NoBitrToutExch,NoBitrTsolExch,NoBitResTair,"\n");
    char* str = malloc( length + 1 );
    snprintf( str, length + 1,"%d %.4g %.4g %.4g %.4g",itimensinc,NoBitrTairExch,NoBitrToutExch,NoBitrTsolExch,NoBitResTair,"\n");
    char buffer[1024] = {0}; 
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
    { 
        printf("\n Socket creation error \n"); 
        return; 
    } 

    memset(&serv_addr, '0', sizeof(serv_addr)); 

    serv_addr.sin_family = AF_INET; 
    serv_addr.sin_port = htons(PORT); 

    // Convert IPv4 and IPv6 addresses from text to binary form 
    if(inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0)  
    { 
        printf("\nInvalid address/ Address not supported \n"); 
        return; 
    } 

    if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) 
    { 
        printf("\nConnection Failed \n"); 
        return; 
    } 

    send(sock , str , strlen(str) , 0 ); 
    printf("Hello message sent\n"); 
    valread = read( sock , buffer, 1024); 
    printf("%s\n",buffer ); 

/* Define temporary variables */
    char *eptr;
    double result;
    result = strtod(buffer, &eptr);
    printf("return value\n"); 
    printf("%.2lf",result);
    *ResTair=result;

    return; 
} 

Кстати, я уже разместил это на форуме сообщества R здесь: https://community.rstudio.com/t/is-there-anything-faster-than-readlines-in-r/23346/5

Заранее спасибо.

1 Ответ

0 голосов
/ 11 февраля 2019

Как написано, C-программа не отправляет символ новой строки (\n) через сокет.Ваш R-клиент ожидает перехода на новую строку, чтобы завершить либо readLines, либо scan, и он делает это до тех пор, пока не достигнет значения по умолчанию 1 минутное время ожидания для сетевых подключений R.

Неправильная строка в коде C здесь:

snprintf(str, length + 1,
         "%d %.4g %.4g %.4g %.4g",  /* <-- 5 format specifiers */
         itimensinc,NoBitrTairExch,NoBitrToutExch,NoBitrTsolExch,NoBitResTair,  /* <-- 5 things to format */
         "\n");  /* <-- this is never added to str */

Функция C snprintf, как и все функции семейства printf, будет молча игнорировать дополнительные аргументы, которые не вписываются встрока формата.

Попробуйте либо включить символ новой строки в самой строке формата, либо добавить спецификатор формата строки или символа:

snprintf(str, length + 1,
         "%d %.4g %.4g %.4g %.4g\n",  /* <-- 5 format specifiers and a newline */
         itimensinc,NoBitrTairExch,NoBitrToutExch,NoBitrTsolExch,NoBitResTair);  /* <-- 5 things to format */

/* or */

snprintf(str, length + 1,
         "%d %.4g %.4g %.4g %.4g%c",  /* <-- 6 format specifiers */
         itimensinc,NoBitrTairExch,NoBitrToutExch,NoBitrTsolExch,NoBitResTair,'\n');  /* <-- 6 things to format */
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...