c - 将操作应用于 C 中的整个内存块

标签 c r

据我所知,在 C 语言中,为了将数组乘以标量,您必须使用 for 循环遍历每个元素。据我所知,R 软件环境的源代码主要是用 C 语言编写的。当我在 R 中有一个大矩阵时,如 mat = matrix(5, nrow = 1100, ncol = 1100) 然后乘以一个常数并测量这个操作的时间,就像这样:

t_start = Sys.time()
mat = mat *5 
print(Sys.time()-t_start)

输出:

Time difference of 0.005984068 secs

但是使用 for 循环做同样的事情,会花费太多时间:

t_start = Sys.time()
for(i in 1:1100)
{
  for(j in 1:1100)
  {
    mat[i,j] = mat[i,j] * 5
  }
}
print(Sys.time()-t_start)

输出:

Time difference of 0.1437349 secs

第二种方式慢了 ~24 倍,现在我假设第一种方式在幕后也是使用 for 循环完成的,如果是这样,为什么时间差异太大?!

我想知道是否有更好的方法将操作应用于 C 中的整个内存块,而无需使用循环遍历每个元素。 我想从 C 语言的角度得到一些答案,因为我目前正在使用 C。那些 R 代码片段只是为了展示 R 提供而 C 不提供的两种不同的执行方式。

最佳答案

即使使用C语言的for循环,也比R语言的第一种方式快。 所以你不必担心 c 语言中的 for-loop 变慢。 查看下面的结果。

C 语言 for 循环:0.00093478

gcc -otest test.c -g -Wall -O2
./test
Time difference of 0.00093478 secs

R语言第一种方式:0.004915237

./Rscript first.R 
Time difference of 0.004915237 secs

test.c代码:

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

typedef struct matrix {
    int nrow;
    int ncol;
    int *buf;
    int *(array[]);
} matrix;

double sys_time()
{
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    return ts.tv_sec + ts.tv_nsec / 1000000000.0;
}

void test(matrix *mat)
{
    int i, j;
    double t_start, t_end;

    t_start = sys_time();
    for(i = 0; i < mat->nrow; i++) {
        for(j = 0; j < mat->ncol; j++) {
            mat->array[i][j] *= 5;
        }
    }
    t_end = sys_time();
    printf("Time difference of %g secs\n", t_end - t_start);
}

matrix *create_matrix(int val, int nrow, int ncol)
{
    matrix *mat;
    int *buf;
    int i, j;

    mat = (matrix *)malloc(sizeof(*mat) + nrow * sizeof(int *));
    buf = (int *)malloc(sizeof(int) * nrow * ncol);
    mat->buf = buf;
    mat->nrow = nrow;
    mat->ncol = ncol;
    for(i = 0; i < nrow; i++) {
        for(j = 0; j < ncol; j++)
            buf[j] = val;
        mat->array[i] = buf;
        buf += ncol;
    }
    return mat;
}

void destroy_matrix(matrix *mat)
{
    free(mat->buf);
    free(mat);
}

int main()
{
    matrix *mat;

    mat = create_matrix(5, 1100, 1100);
    test(mat);
    destroy_matrix(mat);

    return 0;
}

关于c - 将操作应用于 C 中的整个内存块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55047914/

相关文章:

r - 任意重新排序 R 中的直方图列

r - 如何从另一个表的列中获取最接近的匹配字符串和分数?

r - 如何按 R 中列中的次数拆分行?

c++ - 向 snprintf 提供空指针时的预期行为

c# - 在 .NET 的 *.a 库中使用 C 函数

c - C 中的 malloc,但使用多维数组语法

r - 如何使用复选框以交互方式从 visNetwork 中过滤节点/边? (使用 R Shiny )

r - 在变量中搜索字符串并返回匹配的字符串

c - 访问结构体成员时出现段错误

c - 使用 sscanf 迭代