2010-11-30 15 views
0

J'ai un projet C que j'utilise avec Alchemy. Le projet a des tests de ligne de commande post-construction que j'aimerais utiliser avec swfbridge.swfbridge et de gros fichiers

Ces tests s'exécutent, mais ils sont extrêmement lent. Le problème est qu'ils lisent des fichiers modérément volumineux (~ 3 Mo) en mémoire. L'exécution de ces mêmes tests avec les mêmes fichiers via une Alchemy régulière (par exemple, en n'utilisant pas swfbridge mais en utilisant supplyFile d'AS) est très rapide.

Je pense que le goulot d'étranglement est le swfbridge. Plus spécifiquement, de la manière dont swfbridge charge les fichiers. Il les lit et les transmet en fragments de 1024 octets à travers la connexion localhost au swf d'alchimie principal. (Vous pouvez le voir dans swfbridge.log.)

Ma question est la suivante: y a-t-il un moyen de rendre swfbridge plus efficace? Puis-je utiliser une taille de bloc différente, par exemple?

Voici un exemple de code de lecture de fichier. Si vous donnez à ce code un fichier ~ 3MB, il exécutera très lentement.

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

Répondre

0

J'ai trouvé une solution de contournement à ce problème.

Lors de l'exécution d'un swf à partir de la ligne de commande, l'entrée/sortie du fichier est très lente car le processus swf récupère le fichier du processus swfbridge via les sockets localhost. Quelque chose à propos de ceci n'est pas optimisé (les gars d'Alchemy ne s'attendaient probablement pas à ce que quelqu'un utilise cela sérieusement). swfbridge est utilisé pour que stdin et stdout fonctionnent. Mais je ne suis pas tout à fait clair sur pourquoi il est utilisé pour le fichier i/o-- le swf est en cours d'exécution dans adl (Air!) Après tout, il a un accès au système de fichiers.

De toute façon, le fait que le swf fonctionne dans Air peut être utilisé. Nous pouvons router fread/fwrite par des méthodes Air (plutôt que par swfbridge) en utilisant le funopen merveilleux. Sa fait un bon bout de code, mais voici une idée de celui-ci:

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

où air_read est comme ceci:

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

L'autre air_fwrite/air_fweek/air_fclose sont similaires. Notez que certaines de ces fonctions (comme AS3_FileFromPath, AS3_GetInProperty, AS3_NewObject, etc) sont mes propres wrappers simples autour de l'API AS3.

Cette approche supprime le goulot d'étranglement de swfbridge et rend les swfs en ligne de commande aussi rapides que les normales.