Re[49]: Работа - с чего начать: С++ или С#?
От: esil  
Дата: 20.03.09 22:14
Оценка: 1 (1) +2
Здравствуйте, 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 минут, и не тестировался на реальных приложениях, тысячи багов, косяков, неоптимальностей и т. д. Суть этого примера в том, чтобы показать, что есть пути решения проблемы, которые можно успешно применять.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.