Skip to content

Instantly share code, notes, and snippets.

@ilammy

ilammy/test.c Secret

Created December 13, 2014 18:03
Show Gist options
  • Save ilammy/be17881cf16c9bae9fbf to your computer and use it in GitHub Desktop.
Save ilammy/be17881cf16c9bae9fbf to your computer and use it in GitHub Desktop.
Why Python is so slow
#include <math.h>
#include <setjmp.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#define TYPE_INT 42
#define TYPE_DOUBLE 73
struct value
{
int type;
int refcount;
};
struct num_int
{
struct value header;
int value;
};
struct num_double
{
struct value header;
double value;
};
void get(struct value* value)
{
value->refcount++;
}
void put(struct value* value)
{
value->refcount--;
if (value->refcount == 0)
free(value);
}
struct value* alloc_int(int value)
{
struct num_int *result;
result = malloc(sizeof(*result));
result->header.type = TYPE_INT;
result->header.refcount = 1;
result->value = value;
return &result->header;
}
struct value* alloc_double(double value)
{
struct num_double *result = NULL;
result = malloc(sizeof(*result));
result->header.type = TYPE_DOUBLE;
result->header.refcount = 1;
result->value = value;
return &result->header;
}
struct value* int_to_double(struct value *value)
{
struct value *result = NULL;
get(value);
if (value->type != TYPE_INT)
return NULL;
result = alloc_double(((struct num_int*) value)->value);
put(value);
return result;
}
struct value* sine(struct value *value)
{
struct value *result = NULL;
get(value);
if (value->type != TYPE_DOUBLE)
return NULL;
result = alloc_double(sin(((struct num_double*) value)->value));
put(value);
return result;
}
struct value* add(struct value *value1, struct value *value2)
{
struct value *result = NULL;
get(value1);
get(value2);
if (value1->type == TYPE_DOUBLE && value2->type == TYPE_DOUBLE)
{
result = alloc_double(((struct num_double*) value1)->value + ((struct num_double*) value2)->value);
}
put(value1);
put(value2);
return result;
}
void inc(struct value *value)
{
get(value);
if (value->type == TYPE_INT)
{
((struct num_int*) value)->value++;
}
put(value);
}
bool le(struct value *value1, struct value *value2)
{
bool result = false;
get(value1);
get(value2);
if (value1->type == TYPE_INT && value2->type == TYPE_INT)
{
result = ((struct num_int*) value1)->value < ((struct num_int*) value2)->value;
}
put(value1);
put(value2);
return result;
}
void print(struct value *value)
{
get(value);
if (value->type == TYPE_DOUBLE)
{
printf("%lf\n", ((struct num_double*) value)->value);
}
put(value);
}
struct value *lim;
struct value *one;
struct value* test()
{
struct value *i;
struct value *sum;
jmp_buf loop_block;
i = alloc_int(0);
sum = alloc_double(0.0);
while (!setjmp(loop_block))
{
struct value *new_sum;
struct value *i_as_double;
struct value *sine_result;
i_as_double = int_to_double(i);
if (!i_as_double)
{
goto error;
}
sine_result = sine(i_as_double);
put(i_as_double);
if (!sine_result)
{
goto error;
}
new_sum = add(sum, sine_result);
put(sine_result);
if (!new_sum)
{
goto error;
}
put(sum);
sum = new_sum;
inc(i);
if (!le(i, lim))
{
longjmp(loop_block, 1);
}
}
put(i);
return sum;
error:
put(sum);
put(i);
return NULL;
}
int main()
{
struct value *result;
one = alloc_int(1);
lim = alloc_int(100000000);
result = test();
print(result);
put(result);
put(lim);
put(one);
}
from math import sin
def test():
sum = 0.0
for i in xrange(100000000):
sum += sin(i)
return sum
print(test())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment