首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >双核字计数器速度慢

双核字计数器速度慢
EN

Stack Overflow用户
提问于 2017-04-20 22:16:29
回答 1查看 68关注 0票数 0

我需要解析一个巨大的文档,其中一个查询要求我在文档的某些字符串中计算单词。这些字符串通常在2000到30000字之间,而我的程序只需要12秒就能解析所有的字符串。花费时间最长的查询并不奇怪,它需要一个单词计数。

我试着用管道和叉子来加速这个过程。

的工作方式:

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

在那之后,我做叉子,通过管道在叉子之间交流。通过管道的是文本的一半的单词计数。然后将它添加到另一半的单词计数中,然后返回总数。

问题:

在一个测试代码示例中,它似乎毫无帮助。执行的时间似乎仍然是一样的,就好像我一蹴而就。

大问题

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

我在哪里需要帮助?

我需要帮助确切地知道为什么我的功能是:

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

( b)在实际计划中花了这么长时间

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

--

,这是代码!

代码语言:javascript
复制
#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;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-04-21 18:54:59

为了跟进我以上的评论:

如果I/O是您的瓶颈:

考虑将文件名传递到单词计数程序中,然后使用简单的fread()fwrite()调用来管理磁盘I/O,这些调用同时读取整个文件。从它的声音,您的文件应该在内存中合理的只有300千字-也许最坏的情况下3 3Meg文件?很快就会进入记忆。

然后,用你的话计算数据上的魔力。我的猜测是,您甚至不需要担心线程之类的问题,因为在内存中进行扫描对于您的任务来说几乎是即时的。见鬼,我敢打赌,即使使用strtok()来寻找空格和标点符号也足够好。

但是,如果我错了,好消息是,这些数据可以很容易地分成多个部分,并传递给各个线程来计数数据,然后在完成后收集和添加。

如果I/O不是,那么上面的练习将毫无收获,但至少可以很快地作为测试用例进行编码。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43530814

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档