cURL / Mailing Lists / curl-library / Single Mail

curl-library

Use memory to ftp upload large image and got a bad performance

From: huafeng wu <wuhuafeng_at_gmail.com>
Date: Fri, 24 Apr 2009 19:02:14 +0800

Hello,

My platform is ARM-Linux.
And my application need to use FTP to upload some large image data with
memory, not with files.
I reference the sample code ftpupload.c and getinmemory.c to write my code.
Unfortunately I got a bad performance when I use memory to transfer image
data(skyshot.h).
The bit rate on My ARM board is nearly 867 bytes/sec.
But if I use the same image data with a file(skyshot.jpg), The bit rate is
raise to 846899 bytes/sec.

Does anyone can help me improve the performance ?

You can turn on/off the MACRO - USE_MEMORY to see the difference.

My code is as below:

#include <curl/curl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>

/*
 * Use file to transfer, if set to 0
 * Use Memory to transfer, if set to 1
 */
#if 1
#include "skyshot.h"
#define USE_MEMORY
#endif

#define IMAGE_FILE_NAME "skyshot.jpg"
#define REMOTE_URL "ftp://10.1.20.237/" IMAGE_FILE_NAME

#ifdef USE_MEMORY
struct MemoryStruct
{
  char *memory;
  size_t size;
};

static size_t ReadMemoryCallback(void *ptr, size_t size, size_t nmemb, void
*pMem)
{
    struct MemoryStruct *pRead = (struct MemoryStruct *)pMem;

    if ((size * nmemb) < 1)
        return 0;

    if (pRead->size)
    {
        *(char *)ptr = pRead->memory[0]; // copy one single byte
        pRead->memory++; // advance pointer
        pRead->size--; // less data left */
        return 1;
    }
    return 0; // no more data left to deliver
}
#endif

int main(int argc, char **argv)
{
    CURL *pCurl;
    FILE *fd;
    double dUploadSpeed, dTotalTime;

#ifdef USE_MEMORY
    struct MemoryStruct sData;

    sData.memory = &skyshot_jpg[0];
    sData.size = LENGTH_OF_FILE_SKYSHOT_JPG;
    printf("Use memory data to transfer\n");
#else
    struct stat file_info;

    /* get the file size of the local file */
    if(stat(IMAGE_FILE_NAME, &file_info))
    {
        printf("Couldnt open '%s': %s\n", IMAGE_FILE_NAME, strerror(errno));
        return 1;
    }

    /* get a FILE * of the same file */
    fd = fopen(IMAGE_FILE_NAME, "rb");
    printf("Use file to transfer\n");
#endif

    curl_global_init(CURL_GLOBAL_ALL);
    pCurl = curl_easy_init();

    if(pCurl)
    {
        curl_easy_setopt(pCurl, CURLOPT_UPLOAD, 1L);
        curl_easy_setopt(pCurl, CURLOPT_URL, REMOTE_URL);

#ifdef USE_MEMORY
        curl_easy_setopt(pCurl, CURLOPT_READFUNCTION, ReadMemoryCallback);
        curl_easy_setopt(pCurl, CURLOPT_READDATA, (void *)&sData);
        curl_easy_setopt(pCurl, CURLOPT_INFILESIZE_LARGE,
(curl_off_t)sData.size);
#else
        curl_easy_setopt(pCurl, CURLOPT_READDATA, fd);
        curl_easy_setopt(pCurl, CURLOPT_INFILESIZE_LARGE,
(curl_off_t)file_info.st_size);
#endif

        curl_easy_perform(pCurl);

        curl_easy_getinfo(pCurl, CURLINFO_SPEED_UPLOAD, &dUploadSpeed);
        curl_easy_getinfo(pCurl, CURLINFO_TOTAL_TIME, &dTotalTime);
        fprintf(stderr, "Speed: %.3f bytes/sec during %.3f seconds\n",
dUploadSpeed, dTotalTime);

        curl_easy_cleanup(pCurl);
    }
#ifndef USE_MEMORY
    fclose(fd);
#endif
    curl_global_cleanup();

    return 0;
}

Thanks in advance

  • application/octet-stream attachment: ftp.c
skyshot.jpg
  • application/octet-stream attachment: skyshot.h
Received on 2009-04-24