0

Alchemyで使用しているCプロジェクトがあります。プロジェクトには、swfbridgeを使用して実行したいビルド後のコマンドラインテストがいくつかあります。

これらのテストは実行されますが、非常に低速です。問題は、適度に大きなファイル(〜3MB)をメモリに読み込むことです。通常のAlchemyを介して同じファイルでこれらの同じテストを実行する(たとえば、swfbridgeを使用せず、ASからのsupplyFileを使用する)のは非常に高速です。

ボトルネックはswfbridgeだと思います。より具体的には、swfbridgeがファイルをロードする方法です。それらを読み込み、ローカルホスト接続を介して1024バイトのチャンクでメインの錬金術swfに送信します。(これはswfbridge.logで確認できます。)

私の質問は、swfbridgeをより効率的にする方法はありますか?たとえば、別のチャンクサイズを使用させることはできますか?

ファイル読み取りコードの例を次に示します。このコードに約3MBのファイルを指定すると、実行速度が非常に遅くなります。

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>

size_t filesize(const char filename[]) {
    struct stat stbuf;
    if (stat(filename, &stbuf) == -1) {
        fprintf(stdout, "file_size: can't find %s\n...\n", filename);
        return (-1);
    }
    return stbuf.st_size;
}

int main(int argc, char **argv) {
    const char *filename= argv[1];
    size_t size= filesize(filename);

    printf("allocating %d bytes \n", size); fflush(stdout);
    char *data= (char*)malloc(size);

    printf("reading %d bytes \n", size); fflush(stdout);
    FILE *file= fopen(filename, "r");
    fread(data, size, 1, file);

    printf("done \n"); fflush(stdout);
    free(data);
    fclose(file);

    return 0;
}
4

1 に答える 1

0

私はこの問題の回避策を見つけました。

コマンドラインからswfを実行する場合、swfプロセスがローカルホストソケットを介してswfbridgeプロセスからファイルを取得しているため、ファイルのI/Oは非常に遅くなります。これについての何かは最適化されていません(錬金術の人はおそらく誰かがこれを真剣に使用することを期待していませんでした)。swfbridgeは、stdinとstdoutが機能するように使用されます。しかし、なぜファイルI / Oに使用されるのか(結局、swfはadl(Air!)で実行されているのか)、ファイルシステムにアクセスできるのか完全にはわかりません。

とにかく、swfがAirで実行されているという事実を使用することができます。素晴らしいfunopenを使用することで、(swfbridgeではなく)Airメソッドを介してfread/fwriteをルーティングできます。それは実際にはかなりのコードですが、ここにそのアイデアがあります:

FILE* air_fopen(const char filename[], const char mode[]) {
    AS3_Val file= AS3_FileFromPath(filename);

    AS3_Val FileModeClass= AS3_GetClass("flash.filesystem", "FileMode");
    AS3_Val fileMode     = AS3_GetS(FileModeClass, fopenModeToAirMode(mode));

    AS3_Val fileStream   = AS3_NewObject("flash.filesystem", "FileStream"); 
    AS3_CallTS("open", fileStream, "AS3ValType, AS3ValType", file, fileMode);

    AS3_Release(FileModeClass);
    AS3_Release(fileMode);  
    AS3_Release(file);

    return funopen(fileStream,
                   (funopen_read_t)air_fread, (funopen_write_t)air_fwrite,
                   (funopen_seek_t)air_fseek, (funopen_close)air_fclose);
} 

ここで、air_readは次のようになります。

int air_fread(AS3_Val fileStream, char *dest, int size) {
    int bytesAvailable= AS3_GetIntProperty(fileStream, "bytesAvailable");
    if (bytesAvailable <= 0) {
        return 0;
    } else if (size > bytesAvailable) {
        size= bytesAvailable;
    }

    AS3_CallTS("readBytes", fileStream, "AS3ValType, IntType, IntType", AS3_Ram(), dest, size);

    return size;
}

他のair_fwrite/air_fweek/air_fcloseも同様です。これらの関数の一部(AS3_FileFromPath、AS3_GetInProperty、AS3_NewObjectなど)は、AS3APIの独自の単純なラッパーであることに注意してください。

このアプローチにより、swfbridgeのボトルネックが解消され、コマンドラインswfsが通常のswfsと同じように高速になります。

于 2010-12-06T16:53:48.860 に答える