2010-11-30 25 views
0

Ich habe ein C-Projekt, das ich mit verwende. Das Projekt hat einige Post-Build-Befehlszeilen-Tests, die ich mit der swfbridge ausführen möchte.swfbridge und große Dateien

Diese Tests laufen, aber sie sind extrem langsam. Das Problem ist, dass sie einige mäßig große Dateien (~ 3 MB) in den Speicher lesen. Das Ausführen derselben Tests mit den gleichen Dateien über reguläre Alchemie (z. B. keine Verwendung von swfbridge, aber Verwendung von supplyFile von AS) ist sehr schnell.

Ich denke, der Engpass ist die swfbridge. Genauer gesagt, in der Art, wie swfbridge Dateien lädt. Er liest sie ein und überträgt sie in 1024 Byte großen Blöcken über die localhost-Verbindung zum Haupt-Alchemy swf. (Sie können dies in der swfbridge.log sehen.)

Meine Frage ist: Gibt es eine Möglichkeit, Swfbridge effizienter zu machen? Kann ich zum Beispiel eine andere Chunk-Größe verwenden?

Hier ist ein Beispiel für den Code zum Lesen von Dateien. Wenn Sie diesem Code eine ~ 3MB Datei geben, wird sehr langsam ausgeführt.

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

Antwort

0

Ich habe eine Lösung für dieses Problem gefunden.

Wenn ein swf von der Befehlszeile ausgeführt wird, ist die Datei-E/A wirklich langsam, da der swf-Prozess die Datei aus dem swfbridge-Prozess über localhost-Sockets abruft. Etwas daran ist nicht optimiert (die Alchemie-Jungs haben wahrscheinlich nicht erwartet, dass irgendjemand dies ernst nimmt). swfbridge wird verwendet, damit stdin und stdout funktionieren. Aber ich bin nicht ganz klar, warum es für Datei-I/O verwendet wird - die SWF läuft in Adl (Air!) Immerhin-- es hat Dateisystemzugriff.

Wie auch immer, die Tatsache, dass der SWF in Air läuft, kann verwendet werden. Wir können fread/fwrite durch Air-Methoden (anstatt über swfbridge) routen, indem wir das wunderbare funopen verwenden. Es ist eigentlich ein gutes Stück Code, aber hier ist eine Idee davon,

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

wo air_read ist wie folgt:

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

Die andere air_fwrite/air_fweek/air_fclose ähnlich sind. Beachten Sie, dass einige dieser Funktionen (wie AS3_FileFromPath, AS3_GetInProperty, AS3_NewObject usw.) meine eigenen einfachen Wrapper um die AS3 API sind.

Dieser Ansatz entfernt den Swfbridge-Engpass und macht Befehlszeilen-swfs genauso schnell wie normale.

Verwandte Themen