#include "stdafx.h"
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <string.h>
#include <stack>
#include <functional>
#include <string>
typedef void(*clsr_void_call_t)(void*);
typedef void(*clsr_void_destroy_t)(void*);
typedef struct clsr_void_t
{
clsr_void_call_t call;
clsr_void_destroy_t destroy;
} clsr_void;
#define CLSR_VOID_INIT(f) { f , 0 }
inline void clsr_void_destroy(clsr_void* p)
{
if (p->destroy)
p->destroy(p);
}
inline void clsr_void_delete(clsr_void* p)
{
if (p)
{
clsr_void_destroy(p);
free(p);
}
}
inline void clsr_void_init(clsr_void* closure,
clsr_void_call_t call,
clsr_void_destroy_t destroy)
{
closure->call = call;
closure->destroy = destroy;
}
inline clsr_void* clsr_void_create(clsr_void_call_t call,
clsr_void_destroy_t destroy)
{
clsr_void* closure = (clsr_void*)malloc(sizeof(clsr_void));
if (closure)
{
clsr_void_init(closure, call, destroy);
}
return closure;
}
inline void clsr_void_call(clsr_void* p)
{
p->call(p);
}
struct clsr_void_str_t;
typedef void(*clsr_void_str_call_t)(clsr_void_str_t*);
typedef void(*clsr_void_str_call_t2)(const char*);
typedef struct clsr_void_str_t
{
clsr_void_t base;
const char* text;
} clsr_void_str;
#define CLST_VOID_STR_INIT {0,0,0}
int clsr_void_str_init(clsr_void_str * closure,
clsr_void_str_call_t call,
const char* text);
static void clsr_void_str_destroy(void* pv)
{
clsr_void_str * p = (clsr_void_str *)(pv);
free((void*)p->text);
}
int clsr_void_str_init(clsr_void_str * closure,
clsr_void_str_call_t call,
const char* text)
{
clsr_void_init((clsr_void*)closure,
(clsr_void_call_t)call,
&clsr_void_str_destroy);
closure->text = (const char*)malloc(sizeof(char) * (strlen(text) + 1));
if (closure->text)
{
strcpy((char*)closure->text, text);
return 0;
}
return 1;
}
clsr_void* clsr_void_str_create(clsr_void_str_call_t call, const char* text)
{
clsr_void_str * closure = (clsr_void_str*)malloc(sizeof(clsr_void_str));
if (closure)
{
if (clsr_void_str_init(closure, call, text) != 0)
{
free(closure);
closure = 0;
}
}
return (clsr_void*)closure;
}
typedef struct clsr_void_stack_t
{
size_t size;
size_t capacity;
clsr_void** data;
} clsr_void_stack;
#define CLSR_VOID_STACK_INIT { 0, 0, 0 }
inline clsr_void* clsr_void_stack_top(clsr_void_stack* p)
{
return p->data[p->size - 1];
}
inline void clsr_void_stack_pop(clsr_void_stack* p, clsr_void** ppItem)
{
*ppItem = p->data[p->size - 1];
p->size -= 1;
}
inline void clsr_void_stack_destroy(clsr_void_stack* p)
{
for (size_t i = 0; i < p->size; i++)
{
clsr_void_delete(p->data[i]);
}
free(p->data);
p->size = 0;
p->data = 0;
p->capacity = 0;
}
size_t clsr_void_stack_reserve(clsr_void_stack* p, size_t nelements)
{
if (nelements > p->capacity)
{
size_t nelem = nelements;
if (p->data == NULL)
{
p->data = (clsr_void**)malloc(nelem * sizeof(clsr_void*));
}
else
{
p->data = (clsr_void**)realloc((void*)p->data, nelem * sizeof(clsr_void*));
}
p->capacity = nelements;
}
return (p->data != 0) ? nelements : 0;
}
static size_t clsr_void_stack_grow(clsr_void_stack* p, size_t nelements)
{
const size_t INITIAL_CAPACITY = 4;
const size_t MAX_CAPACITY = (size_t)(UINT_MAX / sizeof(clsr_void*));
if (nelements > p->capacity)
{
size_t newCap = p->capacity == 0 ? INITIAL_CAPACITY : p->capacity;
while (newCap < nelements)
{
newCap *= 2;
if (newCap < nelements ||
newCap > MAX_CAPACITY)
{
/*overflow check*/
newCap = MAX_CAPACITY;
}
}
return clsr_void_stack_reserve(p, newCap);
}
return p->capacity;
}
inline size_t clsr_void_stack_push(clsr_void_stack* p, clsr_void* pItem)
{
size_t result = clsr_void_stack_grow(p, p->size + 1);
if (result == 0)
{
clsr_void_delete(pItem);
return 0;
}
p->data[p->size] = pItem;
p->size += 1;
return 1;
}
inline void clsr_void_stack_pop_call(clsr_void_stack* stack)
{
clsr_void* p;
clsr_void_stack_pop(stack, &p);
clsr_void_call(p);
clsr_void_destroy(p);
}
void clsr_void_stack_clear(clsr_void_stack* p)
{
for (size_t i = 0; i < p->size; i++)
{
clsr_void_delete(p->data[i]);
}
p->size = 0;
}
#define MAX_COUNT 10000000
static int counter = 0;
static void f(void*)
{
counter++;
}
static void f2(clsr_void_str* p)
{
counter += strlen(p->text);
}
void Test1()
{
for (int i = 0; i < MAX_COUNT; i++)
{
clsr_void_stack stack = CLSR_VOID_STACK_INIT;
clsr_void_stack_push(&stack, clsr_void_create(&f, 0));
clsr_void_stack_push(&stack, clsr_void_str_create(&f2, "thiago"));
while (stack.size)
{
clsr_void_stack_pop_call(&stack);
}
clsr_void_stack_destroy(&stack);
}
}
//#define HAS_MOVE_CAPTURE
void Test2()
{
for (int i = 0; i < MAX_COUNT; i++)
{
std::stack<std::function<void(void)>> st;
st.emplace([]()
{
counter++;
});
std::string s2 = "thiago";
#ifdef HAS_MOVE_CAPTURE
st.emplace([s2 = std::move(s2)]()
#else
st.emplace([s2]()
#endif
{
counter += s2.size();
});
while (st.size())
{
st.top()();
st.pop();
}
}
}
void RunTest(const char* message, void(*test)(void))
{
counter = 0;
time_t start = clock();
test();
printf("%s %d %d\n", message, int(clock() - start), counter);
}
int main(int argc, char* argv[])
{
RunTest("C++", &Test2);
RunTest("C ", &Test1);
return 0;
}
Output 2013
C++ 6453 70000000
C 4116 70000000
HASMOVECAPTURE Output 2015. {{{ C++ 5333 70000000 C 4048 70000000 ```
Output 2015.
C++ 5452 70000000
C 4083 70000000
C 23% faster
Just construction/destruction of stack
//C
for (int i = 0; i < MAX_COUNT; i++)
{
clsr_void_stack stack = CLSR_VOID_STACK_INIT;
clsr_void_stack_destroy(&stack);
}
//C++
for (int i = 0; i < MAX_COUNT; i++)
{
std::stack<std::function<void(void)>> st;
}
C++ 1063 0
C 58 0
statck out of the loop - first call
void Test1()
{
clsr_void_stack stack = CLSR_VOID_STACK_INIT;
clsr_void_stack_push(&stack, clsr_void_create(&f, 0));
for (int i = 0; i < MAX_COUNT; i++)
{
clsr_void_call(clsr_void_stack_top(&stack));
}
clsr_void_stack_destroy(&stack);
}
void Test2()
{
std::stack<std::function<void(void)>> st;
st.emplace([]()
{
counter++;
});
for (int i = 0; i < MAX_COUNT; i++)
{
st.top()();
}
}
VC++ 2015
C++ 152 10000000
C 25 10000000
statck out of the loop - second call
void Test1()
{
clsr_void_stack stack = CLSR_VOID_STACK_INIT;
clsr_void_stack_push(&stack, clsr_void_str_create(&f2, "thiago"));
for (int i = 0; i < MAX_COUNT; i++)
{
clsr_void_call(clsr_void_stack_top(&stack));
}
clsr_void_stack_destroy(&stack);
}
void Test2()
{
std::stack<std::function<void(void)>> st;
std::string s2 = "thiago";
st.emplace([s2]()
{
counter += s2.size();
});
for (int i = 0; i < MAX_COUNT; i++)
{
st.top()();
}
}
C++ 161 60000000
C 72 60000000