Skip to content

Instantly share code, notes, and snippets.

@tanakamura
Last active December 27, 2015 08:29
Show Gist options
  • Save tanakamura/7297025 to your computer and use it in GitHub Desktop.
Save tanakamura/7297025 to your computer and use it in GitHub Desktop.
fast-printf
#include <windows.h>
#include <stdio.h>
#include <ctype.h>
#ifdef _WIN32
#include <windows.h>
double
sec()
{
LARGE_INTEGER freq, v;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&v);
return v.QuadPart / (double)freq.QuadPart;
}
#else
#include <sys/time.h>
#include <fcntl.h>
double
sec()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec + tv.tv_usec / 1000000.0;
}
#endif
#define BUFSIZE 16384
typedef struct printf_output_ {
char *buffer; /* +0 */
int cur; /* +4 */
HANDLE fd;
int bufsize;
} printf_output;
printf_output *
printf_open(const char *path)
{
printf_output *ret;
HANDLE h = CreateFile(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
if (h == INVALID_HANDLE_VALUE) {
return NULL;
}
ret = malloc(sizeof(*ret));
ret->fd = h;
ret->cur = 0;
ret->bufsize = BUFSIZE;
ret->buffer = malloc(BUFSIZE);
return ret;
}
int write_total;
printf_output *log_file;
FILE *log_file2;
static void
flush(printf_output *out)
{
WriteFile(out->fd, out->buffer, out->cur, NULL, NULL);
out->cur = 0;
}
void
printf_close(printf_output *out)
{
flush(out);
CloseHandle(out->fd);
free(out->buffer);
free(out);
}
static __inline void
output(int len, printf_output *out, const char *data)
{
#if 0
/* len = ecx
* out = edx
* data = sp[4] */
__asm {
mov esi, [esp+4]; /* data */
push edi;
push esi;
mov edi, [edx]; /* out->buffer */
mov eax, [edx+4]; /* out->cur */
add edi, eax; /* edi = buffer + cur */
add eax, ecx; /* cur += len */
/* ecx = len */
rep movsb;
mov [edx+4], eax; /* out->cur = cur */
pop esi;
pop edi;
ret 4;
}
#else
int i;
unsigned char *dst = (unsigned char*)out->buffer + out->cur;
//memcpy(dst, data, len);
//isdigit(data[0]);
for (i=0; i<len; i++) {
dst[i] = data[i];
}
out->cur += len;
#endif
}
static void
reserve(printf_output *out, int len)
{
int bufsize = out->bufsize;
int cur = out->cur;
int rem = bufsize - cur;
if (len <= rem) {
return;
}
flush(out);
if (len >= bufsize) {
bufsize = len * 2;
free(out->buffer);
out->buffer = malloc(bufsize);
}
}
//int __declspec(noinline)
//fast_fprintf(printf_output *out,
// const char *fmt,
// ...)
//{
// //int len = strlen(fmt);
// int len = 17;
//
// reserve(out, len);
// output(out, (unsigned char*)fmt, len);
//
// return len;
//}
static int
output_digit(printf_output *out, int v)
{
char buffer[32];
int cur = 31;
int neg = 0;
int len;
if (v < 0) {
neg = 1;
v = -v;
}
while (v>=10) {
int out = v%10;
buffer[cur--] = out + '0';
v /= 10;
}
buffer[cur--] = v + '0';
if (neg) {
buffer[cur--] = '-';
}
len = 31-cur;
reserve(out, len);
output(len, out, buffer + cur + 1);
return len;
}
static int
output_hex(printf_output *out, unsigned int v)
{
char buffer[32];
int cur = 31;
static const char tbl[] = "0123456789abcdef";
int len;
while (v>=16) {
int out = v&15;
buffer[cur--] = tbl[out];
v >>= 4;
}
buffer[cur--] = tbl[v];
len = 31-cur;
reserve(out, len);
output(len, out, buffer + cur + 1);
return len;
}
int __declspec(noinline)
fast_fprintf(printf_output *out,
const char *fmt,
int v0, int v1, int v2)
{
int len = 2 + 3 + 5 + 1;
reserve(out, 2);
output(2, out, "x=");
len += output_digit(out, v0);
reserve(out, 3);
output(3, out, " y=");
len += output_digit(out, v1);
reserve(out, 5);
output(5, out, " sum=");
len += output_digit(out, v2);
reserve(out, 1);
output(1, out, "\n");
return len;
}
int
sum_printf2(unsigned char *data, int w, int h)
{
int ret = 0;
int xi, yi;
for (yi=0; yi<h; yi++) {
for (xi=0; xi<w; xi++) {
ret += data[yi*w + xi];
//isdigit((char)ret);
write_total += fast_fprintf(log_file, "x=%d y=%d sum=%d\n", xi, yi, ret);
//write_total += fprintf(log_file2, "x=%d y=%d sum=%d\n", xi, yi, ret);
}
}
return ret;
}
int main(int argc, char **argv)
{
unsigned char *data;
int w = 640, h = 480;
int v;
double start, end;
int i;
if (argc >= 3) {
w = atoi(argv[1]);
h = atoi(argv[2]);
}
log_file = printf_open("log.txt");
log_file2 = fopen("log2.txt", "w");
data = malloc(w*h);
memset(data, 0, w*h);
for (i=0; i<5; i++) {
double dt;
const char *name = "??";
write_total = 0;
start = sec();
v = sum_printf2(data, w, h);
name = "printf2";
end = sec();
dt = end-start;
printf("%10s: %d %d %d %f[usec] %f[nsec/byte]\n", name, w, h, v, dt*1000*1000.0, dt/(write_total)*1000*1000*1000.0);
}
printf_close(log_file);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment