gpt4 book ai didi

c - 双核字数统计速度慢

转载 作者:行者123 更新时间:2023-11-30 14:58:01 25 4
gpt4 key购买 nike

我需要解析一个巨大的文档,其中一个查询要求我计算文档某些字符串中的单词数。这些字符串通常有 2000 到 30000 个单词,我的程序需要约 12 秒才能解析所有字符串。毫不奇怪,耗时最长的查询是需要字数统计的查询。

我尝试使用管道和 fork 来加速这个过程。

工作原理:

我将字符串除以二。如果我碰巧将一个单词一分为二 - if text[i] != ' ' etc - 那么分割后的文本的左侧会一直向左看,直到遇到空格并且只计算单词数直到到达那个空间。右侧将该半个单词计为一个完整单词,并继续计数,直到到达字符串末尾。如果我在空格之间划分,循环就不会发生,程序将继续下一步。编辑:可以是空格或 \n\t

之后,我创建一个 fork 并通过管道在 fork 之间进行通信。通过管道的是文本的其中一半的字数统计。然后将其添加到另一半的字数中并返回总数。

问题:

在测试代码示例中,它似乎根本没有帮助。执行时间似乎仍然和我一口气完成的一样。

大问题

该函数在整个解析过程中运行大约 60000 次。而且我的程序执行时间太长,事实上我不得不在 2 分钟后取消它......

我在哪里需要帮助?

我需要帮助才能确切地了解我的功能为何:

a)与单核实现相比,这种所谓的双核实现甚至没有稍微快一点。

b) 在实际程序中花了这么长时间

<小时/>

我希望这不是 C 的问题, fork /管道对于我想要的东西来说太慢了,我希望我只是不知道一些东西。

--

这是代码!

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

long count(char* xStr) {
long num = 0;

// state:
const char* iterar = (const char*) xStr;
int in_palavra = 0;

do switch(*iterar) {
case '\0':
case ' ': case '\t': case '\n':
if (in_palavra) { in_palavra = 0; num++; }
break;
default: in_palavra = 1;
} while(*iterar++);

return num;
}


long wordCounter(char* text) {
int LHalf = strlen(text)/2;
int DHalf = LHalf;
while(text[LHalf] != ' ' && text[LHalf] != '\n' && text[LHalf] != '\t') {
if(LHalf > 0){
LHalf--;
}
else break;
}
char* lft = malloc(LHalf);
char* rgt = malloc(DHalf);

strncpy(lft, text, LHalf);
strncpy(rgt, text + DHalf, DHalf);

int fd[2];
pid_t childpid;
pipe(fd);

long size_left;
long size_right;
if((childpid = fork()) == -1) {
perror("Error in fork");
}

if(childpid == 0) {
close(fd[0]);

size_left = count(lft);
int w = write(fd[1], &size_left, sizeof(long));
close(fd[1]); //desnecessario
exit(0);
}

else {
close(fd[1]);

int r = read(fd[0], &size_left, sizeof(long));
size_right = count(rgt);
close(fd[0]);
wait(0);
}

long total = size_right + size_left;


free(lft);
free(rgt);
return total;
}

int main(int argc, char const *argv[]) {
long num = wordCounter("aaa aaa aa a a a a a a sa sa as sas sa sa saa sa sas aa sa sas sa sa"); //23 words
printf("%ld\n", num);
return 0;
}

最佳答案

跟进我上面的评论:

如果 I/O 是您的瓶颈:

考虑将文件名传递到字数统计程序中,然后使用读取整个文件的简单 fread()fwrite() 调用自行管理光盘 I/O立刻进来。从它的声音来看,你的文件应该只适合 300k 字的内存 - 也许最坏的情况是 3Meg 文件?这应该很快读入内存。

然后,对数据进行字数统计。我的猜测是,您甚至不需要担心线程等,因为扫描内存对于您的任务来说几乎是即时的。哎呀,我敢打赌甚至使用 strtok() 查找空格和标点符号可能就足够了。

但如果我错了,好消息是这些数据可以轻松地分为多个部分并传递给各个 pthread 来计算数据,然后在完成后进行收集和添加。

如果 I/O 不是,那么上面的练习将根本没有任何收获,但至少可以很快地将其编码为测试用例。

关于c - 双核字数统计速度慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43530814/

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