Здравствуйте, gandjustas, Вы писали:
G>Стоит учесть что каждый проход GC в программе на C# очищает вс первое поколение в таком случа и двигание объектов не происходит, то немного исправляет результат в пользу C#, но даже если бы код на C# работал в 2 раза медленее, то он оказался бы в 3 раза быстрее стандартного аллокатора для C++.
И вот таки да, предположим у нас получилость так, что из-за частых выделений/освобождений памяти наш продукт на С++ работает недопустимо медленно. Что можно с этим сделать? Для начала собрать профиль размеров выделяемых блоков, который нам покажет, что большинство выделяемых блоков имеют размер 256 байт. А дальше можно сделать например так:
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <assert.h>
const size_t block_size = 256;
const int pool_size = 1000;
char * pool;
bool * allocated;
void * operator new[](size_t size) {
if(size > block_size)
return malloc(size);
if(!pool) {
pool = (char*)malloc(pool_size * block_size);
allocated = (bool*)malloc(pool_size * sizeof(allocated[0]));
memset(allocated, 0, pool_size * sizeof(allocated[0]));
}
for(int i = 0; i < pool_size; ++i) {
if(!allocated[i]) {
allocated[i] = true;
return pool + block_size * i;
}
}
return malloc(size);
}
void operator delete[](void * mem) {
char * mem_ch = (char*) mem;
if(mem_ch < pool || mem_ch >= (pool + pool_size * block_size))
return free(mem);
size_t diff = mem_ch - pool;
assert(diff % block_size == 0);
int block_num = diff / block_size;
assert(block_num < pool_size);
allocated[block_num] = false;
}
int _tmain(int argc, _TCHAR* argv[])
{
DWORD ticks = GetTickCount();
for(int i=0; i<1000000; i++)
{
int* arr = new int[64];
delete [] arr;
}
printf("%d", GetTickCount() - ticks);
getchar();
return 0;
}
Запустите это наколеночное решение и прослезитесь. И всё. Пользователи довольны, менеджеры счастливы, программисты радуются, фанатики С++ бъются в экстазе.
Что Вы будете делать с продуктом на С#? Судорожно тыкать в разных местах gc.collect? Срочно переписывать куски кода с использованием структур?
P. S. Я понимаю, что наверняка любители писать свои менеджеры памяти сейчас найдут в моём коде, который был написан за 20 минут, и не тестировался на реальных приложениях, тысячи багов, косяков, неоптимальностей и т. д. Суть этого примера в том, чтобы показать, что есть пути решения проблемы, которые можно успешно применять.