我有一个与Alchemy一起使用的C项目。该项目有一些构建后的命令行测试,我想使用swfbridge运行。
这些测试运行,但它们非常慢。问题是他们将一些中等大小的文件(~3MB)读入内存。通过常规Alchemy使用相同的文件运行这些相同的测试(例如,不使用swfbridge但使用来自AS的supplyFile)非常快。
我认为瓶颈是swfbridge。更具体地说,就像swfbridge加载文件的方式一样。它读入它们并通过localhost连接以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;
}
答案 0 :(得分: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瓶颈,使命令行swfs与普通swfs一样快。