0

我有一个与Alchemy一起使用的 C 项目。该项目有一些我想使用 swfbridge 运行的构建后命令行测试。

这些测试运行,但它们非常慢。问题是他们将一些中等大小的文件(~3MB)读入内存。通过常规 Alchemy 使用相同的文件运行这些相同的测试(例如,不使用 swfbridge 而是使用 AS 的 supplyFile)非常快。

我认为瓶颈是swfbridge。更具体地说,以 swfbridge 加载文件的方式。它读取它们并通过 localhost 连接将它们以 1024 字节块的形式传输到主 alchemy 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 时,文件 i/o 非常慢,因为 swf 进程通过 localhost 套接字从 swfbridge 进程获取文件。这方面的一些事情是未优化的(炼金术的人可能没想到有人会认真地使用它)。使用 swfbridge 以便 stdin 和 stdout 可以工作。但我并不完全清楚它为什么用于文件 i/o——毕竟 swf 在 adl(Air!)中运行——它具有文件系统访问权限。

无论如何,可以使用 swf 在 Air 中运行的事实。我们可以使用美妙的 funopen 通过 Air 方法(而不是通过 swfbridge)路由 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 等)是我自己对 AS3 api 的简单包装。

这种方法消除了 swfbridge 瓶颈,并使命令行 swf 与普通 swf 一样快。

于 2010-12-06T16:53:48.860 回答