C 语言 循环下 创建动态数组 非常慢 应该如何解决

2022-07-05 16:07:03 +08:00
 hhhhhh123

我简单阐述下背景: 我不是专业 C 开发人员, 我是 python 开发。 因为 python 部分功能实现慢,故使用 C 来重写然后进行封装动态库进行调用。 所有项目用的是 C 不是 C++ 。 目前是已经完成了 速度也有很大的提升。 但是我发现应该还能提升 。 下面代码就是一个例子。。

我要循环一个很大的值 百万级别甚至上亿。 然后动态数组, 但是这个创建动态数组非常慢,各位 C 大佬有什么方法可以解决吗? 还是说我的操作有问题??? 非专 C 人员,勿喷, 如果可以的话,救救孩纸吧.

下面迭代了 132963138 次数的耗时情况

for (int ii = 0; ii < arr_cnt_copy; ii++) {

count += 1;
int min_score = 7462; // 200 ms
int* res_card_lst = (int*)malloc(c_ * sizeof(int)); // 25s

}

2899 次点击
所在节点    C
35 条回复
e9pWeUbh9PGCnp95
2022-07-05 17:55:46 +08:00
由于操作系统的惰性分配有关, 请提前申请内存,并提前触发缺页中断, 这样能够确保内存立即能够使用.
ty359
2022-07-05 18:02:39 +08:00
@hhhhhh123 那你要么转用 C++,不然就多注意一点,C 不像 Python ,是没有自动内存回收的,而且例如文件描述符也是需要手动管理的,在这个角度 C 比 C++要麻烦不少;
另外你不能因为好像 C/C++比 Python 快就去改用 C/C++,你最好得明白 C/C++该怎么用;一个 C/C++新手写出来的科学计算程序可能还不如 numpy 的性能。
documentzhangx66
2022-07-05 18:19:37 +08:00
1.malloc 以及类似的内存分配、重分配、销毁等 API ,其本质是一个规划管理问题,运算量非常耗时。很多朋友只调用它一次,当然感受不到它的慢。

因此,很多大佬,会根据需求,自己实现 xxMaloc ,来根据需求定制化地管理内存,不用原生的 malloc ,来进行加速。


2.我还是建议楼主,重开一贴,专门讲讲你的需求,可能会有更好的方案。


3.楼主觉得,这个问题上 C 比 Python 强,但楼主需要思考一下,为什么 Python 还那么流行。
mxT52CRuqR6o5
2022-07-05 18:27:38 +08:00
我觉得你可以试试 c#,前几天站里有个人发语言性能排名,c#是有 gc 带 runtime 里面最快的
BrettD
2022-07-05 18:29:42 +08:00
@mxT52CRuqR6o5 但是 C#和 Python 互操作目前有简单的解决方案吗?
stephenyin
2022-07-05 19:11:42 +08:00
@mxT52CRuqR6o5 #24 OP 的环境 c++ 都跑不起来,C# 更没可能咯。

话说 OP 应该给项目提议招个 C/C++ 程序员。
tairan2006
2022-07-05 21:22:54 +08:00
我还以为 c 里面直接声明一个超大数组是常识,当然你可以试试内存池之内的玩意儿
chenxytw
2022-07-05 22:13:28 +08:00
我的建议是,用 Cython.
ToBeHacker
2022-07-05 22:31:53 +08:00
malloc 是系统调用,频次太高也会有性能问题的
MeePawn666
2022-07-06 06:47:38 +08:00
@ToBeHacker 小杠一下,malloc 不是系统调用,底层的 brk 和 mmap 才是
LANB0
2022-07-06 10:11:31 +08:00
@tairan2006 栈区超大数组是很可能造成栈溢出的,怎么会有常识一说?楼主只是没有认识到动态内存申请是需要耗时的,把动态内存申请放在循环外即可解决,对于循环外函数频繁调用的,使用全局或者静态指针申请一次即可,内存池对非 C 开发人员来说,要求高了点。
ToBeHacker
2022-07-06 12:33:56 +08:00
@MeePawn666 是的,malloc 是 C 标准库的实现
hhhhhh123
2022-07-06 14:00:46 +08:00
这是要我重新开个帖子, 把代码贴上 然后找优化点吗?
hhhhhh123
2022-07-06 14:08:52 +08:00
现在优化到 200ms -> 58ms 平均,但是还是太慢了
echoechoin
2022-07-06 17:52:22 +08:00
在 github 找一个内存池用用呗, 想更快还可以使用 linux 的 hugetables 但是感觉用内存池就够了吧

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/864227

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX