Skip to content

Instantly share code, notes, and snippets.

@b4n
Created March 24, 2012 17:41
Show Gist options
  • Save b4n/2185493 to your computer and use it in GitHub Desktop.
Save b4n/2185493 to your computer and use it in GitHub Desktop.
/* old, one loop
*
* With not enough data (< 4096):
* mem_read (..., 1, 4096): 162.099252s (100000000 runs)
* mem_read (..., 4096, 1): 0.967107s (100000000 runs)
* With enough data (>= 4096):
* mem_read (..., 1, 4096): 2274.210934 (100000000 runs)
* mem_read (..., 4096, 1): 10.416469 (100000000 runs)
*/
static size_t
mem_read (MIO *mio,
void *ptr,
size_t size,
size_t nmemb)
{
size_t n_read = 0;
if (size != 0 && nmemb != 0) {
if (mio->impl.mem.ungetch != EOF) {
*((unsigned char *) ptr) = (unsigned char) mio->impl.mem.ungetch;
mio->impl.mem.ungetch = EOF;
mio->impl.mem.pos++;
if (size == 1) {
n_read++;
} else if (mio->impl.mem.pos + (size - 1) <= mio->impl.mem.size) {
memcpy (&(((unsigned char *) ptr)[1]),
&mio->impl.mem.buf[mio->impl.mem.pos], size - 1);
mio->impl.mem.pos += size - 1;
n_read++;
}
}
for (; n_read < nmemb; n_read++) {
if (mio->impl.mem.pos + size > mio->impl.mem.size) {
break;
} else {
memcpy (&(((unsigned char *) ptr)[n_read * size]),
&mio->impl.mem.buf[mio->impl.mem.pos], size);
mio->impl.mem.pos += size;
}
}
if (mio->impl.mem.pos >= mio->impl.mem.size) {
mio->impl.mem.eof = TRUE;
}
}
return n_read;
}
/* new, no loops
*
*
* With not enough data (< 4096):
* mem_read (..., 1, 4096): 2.753983s (100000000 runs)
* mem_read (..., 4096, 1): 1.605477s (100000000 runs)
* With enough data (>= 4096):
* mem_read (..., 1, 4096): 11.102533 (100000000 runs)
* mem_read (..., 4096, 1): 11.146004 (100000000 runs)
*/
static size_t
mem_read (MIO *mio,
void *ptr_,
size_t size,
size_t nmemb)
{
size_t n_read = 0;
if (size != 0 /*&& nmemb != 0*/) {
size_t block_avail = (mio->impl.mem.size - mio->impl.mem.pos) / size;
size_t copy_blocks = MIN (block_avail, nmemb);
unsigned char *ptr = ptr_;
if (copy_blocks > 0) {
if (mio->impl.mem.ungetch != EOF) {
*ptr = (unsigned char) mio->impl.mem.ungetch;
mio->impl.mem.ungetch = EOF;
if (size > 1) {
memcpy (ptr + 1, &mio->impl.mem.buf[mio->impl.mem.pos + 1], size - 1);
}
mio->impl.mem.pos += size;
ptr += size;
n_read++;
copy_blocks--;
}
/*if (copy_blocks > 0)*/ {
size_t copy_size = size * copy_blocks;
memcpy (ptr, &mio->impl.mem.buf[mio->impl.mem.pos], copy_size);
mio->impl.mem.pos += copy_size;
n_read += copy_blocks;
}
}
if (mio->impl.mem.pos >= mio->impl.mem.size) {
mio->impl.mem.eof = TRUE;
}
}
return n_read;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment