C 实现音节化算法,但速度非常慢
我按照改进的Lansky算法实现了简单的音节化算法,但当我需要在超过200万单词的语料库上运行该算法时,它的速度非常慢。有人能告诉我是什么原因导致它这么慢吗?算法如下:C 实现音节化算法,但速度非常慢,c,algorithm,performance,nlp,C,Algorithm,Performance,Nlp,我按照改进的Lansky算法实现了简单的音节化算法,但当我需要在超过200万单词的语料库上运行该算法时,它的速度非常慢。有人能告诉我是什么原因导致它这么慢吗?算法如下: 最后一个元音(元音组)之后的所有内容都属于最后一个音节 第一个元音(元音组)之前的所有内容都属于第一个音节 如果元音之间的辅音数为偶数(2n),则将其分为 一半第一部分属于左元音,第二部分属于右元音(n/n) 如果元音之间的辅音数量是奇数(2n+1),我们将它们分为 n/n+1个零件 如果元音之间只有一个辅音,则属于左元音 #包
#包括
#包括
#定义元音“aeiou”
int get_n_辅音_between(字符*单词,int长度){
整数计数=0;
int i=0;
while(i++<长度){
if(strchr(元音,*单词))中断;
word++;
计数++;
}
返回计数;
}
无效音节化(字符*单词,int n_元音组){
int i=0,length=strlen(单词),辅音;
int音节=0,元音组=0,syl长度=0;
字符*音节=单词;
char hola[长度];
memset(hola,0,长度);
if(n_元音组<2){
printf(“不能拆分为音节\n\n”);
返回;
}
while(i
`您可以做的事情很少: 1) 对程序进行概要分析,并查看其大部分时间都在哪里 2) 专注于代码中最重复的部分 3) 避免多次扫描 4) 不要进行不必要的操作。例如: (a) 您是否需要始终
memset
hola
memset(hola, 0, length);
在我看来,你可以摆脱它
(b)
您可以从分析中获得非常好的提示,遵循这些提示并放大瓶颈 您可以做的事情很少: 1) 对程序进行概要分析,并查看其大部分时间都在哪里 2) 专注于代码中最重复的部分 3) 避免多次扫描 4) 不要进行不必要的操作。例如: (a) 您是否需要始终
memset
hola
memset(hola, 0, length);
在我看来,你可以摆脱它
(b)
您可以从分析中获得非常好的提示,遵循这些提示并放大瓶颈 要检查实现是否正确,需要编写大量代码 正确,主要是因为我不知道术语(比如什么是 元音组)的算法。我查了一下,谷歌给了我很多信息 研究论文(我只能看到摘要)的教学大纲 不同的语言,所以我不确定代码是否正确 但是我有一些建议可以让你的代码更快:
strlen(word)
从循环条件中移出。节省时间
在变量中,并使用该变量。所以从
for (i = 0; i < strlen(word); i++)
当您要检查字符是否为元音时:
// 0x20 | c make c a lower case character
if(vowel[0x20 | word[i]])
syl_length++;
i++;
if (vowel_group) continue;
vowel_group = 1;
}
strchr
必须多次遍历整个“aeiou”
数组。1
我还建议您分析代码。见和
fotenotes 1我制作了一个非常粗糙的程序,比较 建议。我加了一个fe
for (i = 0; i < strlen(word); i++)
size_t len = strlen(word);
for(i = 0; i < len; i++)
// as global variable
char vowels[256];
int main(void)
{
vowels['a'] = 1;
vowels['e'] = 1;
vowels['i'] = 1;
vowels['o'] = 1;
vowels['u'] = 1;
...
}
// 0x20 | c make c a lower case character
if(vowel[0x20 | word[i]])
syl_length++;
i++;
if (vowel_group) continue;
vowel_group = 1;
}
#include <stdio.h>
#include <string.h>
#include <time.h>
int test1(time_t t)
{
char text[] = "The lazy dog is very lazy";
for(size_t i = 0; i < strlen(text); ++i)
t += text[i];
return t;
}
int test2(time_t t)
{
char text[] = "The lazy dog is very lazy";
size_t len = strlen(text);
for(size_t i = 0; i < len; ++i)
t += text[i];
return t;
}
#define VOWELS "aeiou"
char vowels[256];
int test3(time_t t)
{
char text[] = "The lazy dog is very lazy";
size_t len = strlen(text);
for(size_t i = 0; i < len; ++i)
{
if (strchr(VOWELS, text[i]))
t += text[i];
t += text[i];
}
return t;
}
int test4(time_t t)
{
char text[] = "The lazy dog is very lazy";
size_t len = strlen(text);
for(size_t i = 0; i < len; ++i)
{
if(vowels[0x20 | text[i]])
t += text[i];
t += text[i];
}
return t;
}
int main(void)
{
vowels['a'] = 1;
vowels['e'] = 1;
vowels['i'] = 1;
vowels['o'] = 1;
vowels['u'] = 1;
long times = 50000000;
long tmp = 0;
clock_t t1 = 0, t2 = 0, t3 = 0, t4 = 0;
for(long i = 0; i < times; ++i)
{
clock_t start,end;
time_t t = time(NULL);
start = clock();
tmp += test1(t);
end = clock();
t1 += end - start;
//t1 += ((double) (end - start)) / CLOCKS_PER_SEC;
start = clock();
tmp += test2(t);
end = clock();
t2 += end - start;
start = clock();
tmp += test3(t);
end = clock();
t3 += end - start;
start = clock();
tmp += test4(t);
end = clock();
t4 += end - start;
}
printf("t1: %lf %s\n", ((double) t1) / CLOCKS_PER_SEC, t1 < t2 ? "wins":"loses");
printf("t2: %lf %s\n", ((double) t2) / CLOCKS_PER_SEC, t2 < t1 ? "wins":"loses");
printf("t3: %lf %s\n", ((double) t3) / CLOCKS_PER_SEC, t3 < t4 ? "wins":"loses");
printf("t4: %lf %s\n", ((double) t4) / CLOCKS_PER_SEC, t4 < t3 ? "wins":"loses");
printf("tmp: %ld\n", tmp);
return 0;
}