分綴アルゴリズムを実装していますが、本当に遅いです

sushionthefork

改良されたLanskyアルゴリズムに従って単純な音節アルゴリズムを実装しましたが、200万語を超えるコーパスでこのアルゴリズムを実行する必要がある場合は非常に遅くなります。誰かが私をそんなに遅くする原因の方向に向けることができますか?以下のアルゴリズム:

  1. 最後の母音(母音グループ)以降はすべて最後の音節に属します

  2. 最初の母音(母音グループ)の前のすべてが最初の音節に属します

  3. 母音間の子音の数が偶数(2n)の場合、前半は左母音に属し、後半は右母音に属する半分に分割されます(n / n)。

  4. 母音間の子音の数が奇数(2n + 1)の場合、それらをn / n +1の部分に分割します。

  5. 母音の間に子音が1つしかない場合、それは左の母音に属します。

    #include <stdio.h>
    #include <string.h>
    
    #define VOWELS "aeiou"
    
    int get_n_consonant_between(char *word, int length) {
         int count = 0;
         int i = 0;
    
         while (i++ < length) {
              if (strchr(VOWELS, *word)) break;
             word++;
             count++;
         } 
    
         return count;
     }
    
     void syllabification(char *word, int n_vowel_groups) {
         int i = 0, length = strlen(word), consonants;
         int syllables = 0, vowel_group = 0, syl_length = 0;
         char *syllable = word;
         char hola[length];
    
         memset(hola, 0, length);
    
         if (n_vowel_groups < 2) {
             printf("CAN'T BE SPLIT INTO SYLLABLES\n\n");
             return;
         }
    
         while (i < length) {
             if (strchr(VOWELS, word[i])) {
                 syl_length++;
                 i++;
                 if (vowel_group) continue;
                 vowel_group = 1;
             }
             else {
                 if (vowel_group) {
                      consonants = get_n_consonant_between(word + i, length - i);
                      if (consonants == 1) {
                          // printf("only one consonant\n");
                          syl_length++;
                          strncpy(hola, syllable, syl_length);
                          i++;
                      }
                      else {
                          int count = consonants / 2;
                          if ((consonants % 2) == 0) { /* number of consonants is 2n, first half belongs to the left vowel */
                         syl_length += count;
                }
                else {
                    syl_length += count;
                }
                strncpy(hola, syllable, syl_length);
                i += count;
            }
    
            syllables++;
            if (syllables == n_vowel_groups) {
                printf("syllable done %d: %s\n", syllables, syllable);
                break;
            }
            printf("syllable %d: %s\n", syllables, hola);
    
            syllable = word + i;
            syl_length = 0;
            memset(hola, 0, length);
        }
        else {
            syl_length++;
            i++;
        }
        vowel_group = 0;
         }
     }    
     }
    
     int count_vowel_groups(char *word) {
          int i, nvowels = 0;
          int vowel_group = 0;
    
          for (i = 0; i < strlen(word); i++) {
              if (strchr(VOWELS, word[i])) {
                  if (vowel_group) continue;
                  vowel_group = 1;
              }
              else {
                  if (vowel_group) nvowels++;
                  vowel_group = 0;
              }    
          }
          // printf("%d vowel groups\n", nvowels);
          return nvowels;
    }
    
     void repl() {
          char *line = NULL;
          size_t len = 0;
          int i = 0;
          int count;
          FILE *file = fopen("../syllables.txt", "r");
          while(i++ < 15) {
              getline(&line, &len, file);
              printf("\n\n%s\n", line);
              count = count_vowel_groups(line);
              syllabification(line, count);
          }
     }
    
     int main(int argc, char *argv[]) {
         // printf("Syllabification test:\n");
         repl();
     }
    

    `

パブロ

これは、実装が正しいかどうかを確認するために実行する必要のある多くのコードです。主な理由は、アルゴリズムの用語(正確には母音グループとは何かなど)がわからないためです。調べてみると、グーグルがさまざまな言語の音節化に関する多くの研究論文(要約しか見ることができない)を返してきたので、コードがまったく正しいかどうかはわかりません。

しかし、私はあなたのコードをより速くするかもしれないいくつかの提案があります:

  1. すべての人をループ状態strlen(word)から外しforます。長さを変数に保存し、代わりにその変数を使用してください。だからから

    for (i = 0; i < strlen(word); i++)
    

    size_t len = strlen(word);
    for(i = 0; i < len; i++)
    
  2. strchr文字が母音であるかどうかの確認には使用しないでくださいこれにはルックアップテーブルを使用します。

    // 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;
    }
    

最初の提案はあなたにわずかなパフォーマンスの向上を与えるかもしれません、コンパイラはかなり賢くて、とにかくそれを最適化するかもしれません。2番目の提案は、単なるルックアップであるため、パフォーマンスが向上する可能性があります。最悪の場合strchr"aeiou"アレイ全体を何度も通過する必要があります。1

また、コードのプロファイルを作成することをお勧めします。これこれを参照してください


fotenotes

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;
}

結果は次のとおりです。

$ gcc b.c -ob -Wall -O0
$ ./b 
t1: 10.866770 loses
t2: 7.588057 wins
t3: 10.801546 loses
t4: 8.366050 wins

$ gcc b.c -ob -Wall -O1
$ ./b
t1: 7.409297 loses
t2: 7.082418 wins
t3: 11.415080 loses
t4: 7.847086 wins

$ gcc b.c -ob -Wall -O2
$ ./b
t1: 6.292438 loses
t2: 5.855348 wins
t3: 9.306874 loses
t4: 6.584076 wins

$ gcc b.c -ob -Wall -O3
$ ./b
t1: 6.317390 loses
t2: 5.922087 wins
t3: 9.436450 loses
t4: 6.722685 wins

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

JavaのSetはUnionFindアルゴリズムを実装していますか?

分類Dev

Lua(trAInsported):Wavefrontアルゴリズムを実装しようとしていますが、機能しません

分類Dev

CでLuhnのアルゴリズムを実装しようとしています

分類Dev

JSでisRepdigit()アルゴリズムを実装しようとしています

分類Dev

バイナリ検索アルゴリズムの実装の何が問題になっていますか?

分類Dev

C ++ 17並列アルゴリズムはすでに実装されていますか?

分類Dev

DBMSはどのように独自のソートアルゴリズムを実装していますか?それとも彼らですか?

分類Dev

DBMSはどのように独自のソートアルゴリズムを実装していますか?それとも彼らですか?

分類Dev

A-Starアルゴリズム:実装が遅い

分類Dev

K-Daneアルゴリズムの実装の何が問題になっていますか?

分類Dev

補間検索アルゴリズムの実装の何が問題になっていますか?

分類Dev

文字列に一意の文字がすべて含まれているかどうかを判断するアルゴリズムを Scala に実装する

分類Dev

Held-KarpアルゴリズムのJava実装を最適化して、実行時間を短縮するにはどうすればよいですか?

分類Dev

ソートアルゴリズムのこの実装で、ベクトルが配列よりも大幅に遅いのはなぜですか?

分類Dev

メトロポリスアルゴリズム(mcmc)のPython実装が非常に遅いのはなぜですか?

分類Dev

OpenCLは通常のループよりも遅いアルゴリズムを実装しました

分類Dev

アルゴリズムを実装しますか?

分類Dev

Javaでntru暗号化アルゴリズムを実装するにはどうすればよいですか?

分類Dev

PythonでFFTアルゴリズムを実装するには?

分類Dev

Swiftは標準ライブラリにどのようなソートアルゴリズムを実装していますか?

分類Dev

マークルツリーの整合性証明を実装しようとしていますが、アルゴリズムの理解に固執しています

分類Dev

JavaアルゴリズムはCまたはJavaで実装されていますか?

分類Dev

独自のHPSアルゴリズムを実装するにはどうすればよいですか?

分類Dev

再帰的二分アルゴリズムを使用して、文字が文字列に含まれているかどうかを確認します

分類Dev

Eigen3にBartels–Stewartアルゴリズムを実装しますか?

分類Dev

自分でアルゴリズムを学ぶ、Javaでタプルをどのように実装しますか?

分類Dev

「BigOh」表記を使用してこのアルゴリズムを分析するにはどうすればよいですか。また、このアルゴリズムの実行時間を改善するにはどうすればよいですか。

分類Dev

PHP:array_search()に実装されている検索アルゴリズムは何ですか?

分類Dev

500を超える因子を持つ最初の三角数を見つけるアルゴリズムが実行されて遅くなっています

Related 関連記事

  1. 1

    JavaのSetはUnionFindアルゴリズムを実装していますか?

  2. 2

    Lua(trAInsported):Wavefrontアルゴリズムを実装しようとしていますが、機能しません

  3. 3

    CでLuhnのアルゴリズムを実装しようとしています

  4. 4

    JSでisRepdigit()アルゴリズムを実装しようとしています

  5. 5

    バイナリ検索アルゴリズムの実装の何が問題になっていますか?

  6. 6

    C ++ 17並列アルゴリズムはすでに実装されていますか?

  7. 7

    DBMSはどのように独自のソートアルゴリズムを実装していますか?それとも彼らですか?

  8. 8

    DBMSはどのように独自のソートアルゴリズムを実装していますか?それとも彼らですか?

  9. 9

    A-Starアルゴリズム:実装が遅い

  10. 10

    K-Daneアルゴリズムの実装の何が問題になっていますか?

  11. 11

    補間検索アルゴリズムの実装の何が問題になっていますか?

  12. 12

    文字列に一意の文字がすべて含まれているかどうかを判断するアルゴリズムを Scala に実装する

  13. 13

    Held-KarpアルゴリズムのJava実装を最適化して、実行時間を短縮するにはどうすればよいですか?

  14. 14

    ソートアルゴリズムのこの実装で、ベクトルが配列よりも大幅に遅いのはなぜですか?

  15. 15

    メトロポリスアルゴリズム(mcmc)のPython実装が非常に遅いのはなぜですか?

  16. 16

    OpenCLは通常のループよりも遅いアルゴリズムを実装しました

  17. 17

    アルゴリズムを実装しますか?

  18. 18

    Javaでntru暗号化アルゴリズムを実装するにはどうすればよいですか?

  19. 19

    PythonでFFTアルゴリズムを実装するには?

  20. 20

    Swiftは標準ライブラリにどのようなソートアルゴリズムを実装していますか?

  21. 21

    マークルツリーの整合性証明を実装しようとしていますが、アルゴリズムの理解に固執しています

  22. 22

    JavaアルゴリズムはCまたはJavaで実装されていますか?

  23. 23

    独自のHPSアルゴリズムを実装するにはどうすればよいですか?

  24. 24

    再帰的二分アルゴリズムを使用して、文字が文字列に含まれているかどうかを確認します

  25. 25

    Eigen3にBartels–Stewartアルゴリズムを実装しますか?

  26. 26

    自分でアルゴリズムを学ぶ、Javaでタプルをどのように実装しますか?

  27. 27

    「BigOh」表記を使用してこのアルゴリズムを分析するにはどうすればよいですか。また、このアルゴリズムの実行時間を改善するにはどうすればよいですか。

  28. 28

    PHP:array_search()に実装されている検索アルゴリズムは何ですか?

  29. 29

    500を超える因子を持つ最初の三角数を見つけるアルゴリズムが実行されて遅くなっています

ホットタグ

アーカイブ