Сеанс низькорівневої оптимізації використання пам'яті в програмах на мові С + + з повним викриттям

pre {font-family: 'courier new', monospace! important;}. b-typo table td {color: # 0D0D0D! important; font-size: 1em! important;}

«У обчислювальній техніці оптимізацією називається процес модифікації системи для поліпшення її ефективності. Система може бути одиночній комп'ютерною програмою, набором комп'ютерів або навіть цілої мережею, такий як Internet.

Незважаючи на те, що слово "оптимізація" використовує той же самий корінь, що й слово "оптимальний", процес оптимізації досить рідко породжує оптимальну систему, тому завжди є поступки (tradeoffs).

Оптимізація повинна проводитися з обережністю. Тоні Хоар вперше вимовив, і Дональд Кнут згодом часто повторював відомий вислів: "Передчасна оптимізація - це корінь всіх бід". Дуже важливо мати для початку озвучений алгоритм і працюючий прототип. " © wiki

У цій статті ми спробуємо змусити наші алгоритми працювати швидше, використовуючи методики низькорівневої оптимізації виділення пам'яті на С + +. Потрібно розуміти, що всі описані в статті методики повинні застосовується з крайньою обережністю і у виняткових випадках, оскільки за впровадження будь-яких елементів низькорівневої оптимізації часто доводиться платити гнучкістю, переносимістю, зрозумілістю або масштабованістю додатків. Але якщо у вас саме той випадок, коли відступати нікуди, тоді - ласкаво просимо.

1. Оптимізація «Конкретних Фабрик»

Я думаю, багато хто неодноразово стикалися з класичним паттерном «Фабрика», або «Конкретна Фабрика», в термінології GoF:

struct IObject
{
     virtual ~ IObject () {}
     virtual void DoIt () = 0;
};
class CFactory
{
public:
    void CreateSmth (int objType, std:: auto_ptr * pResult)
    {
        if (iValue reset (new CObject1);
        }
        else
        {
            pResult->reset (new CObject2);
        }
    }
};

Паттерн виключно хороший для позбавлення від нескінченних if'ов і switch'ей по всьому коду, але має одну неприємну особливість, пов'язану з надмірним використанням динамічної пам'яті, що іноді неприємно відбивається на продуктивності С + + програм. Ми постараємося відучити його від цього, при певних застереженнях, природно.

Подивимося ще раз на процес використання фабрики:

Дія Сенс
std:: auto_ptr product; ми оголошуємо деякий контейнер для продукції, місце, де буде «зберігатися» створений об'єкт
MySuperFactory.CreateSmth (1, & product); створюємо об'єкт у цьому контейнері з допомогою фабрики
product->DoIt (); використовуємо отриманий об'єкт через відомий інтерфейс
mySuperContainer.Add (product); або передаємо володіння контейнером кому-небудь ще

Для оптимізації описаного життєвого циклу продукції можна застосувати наступні твердження:

1) Спеціальна форма оператора new - placement new дозволяє створювати об'єкти в довільному, «сирому» буфері. Наприклад, так:

char buffer [1024];
new (buffer) CObject (a, b, c);

Дуже корисна річ, враховуючи, що ми можемо виділити буфер більш ефективно, ніж стандартна реалізація new. Правда, використання placement new теж вносить деякі труднощі в життя програміста:

a) Сирий буфер повинен бути вирівняний на границю, залежну від платформи;

b) Деструктор створеного об'єкта повинен бути викликаний вручну.

2) Використання стека є вдалою альтернативою хіпу. Було б набагато більш заманливо використовувати як контейнер буфер на стеку, тобто використовувати

MyWrapperAroundLocalBuffer product;

замість оригінального

std:: auto_ptr product;

Основна проблема створення контейнера на стеку полягає в тому, що в стандартному С + + неможливо виділити на стеку об'єкт довільного розміру (невідомого на етапі компіляції).

3) Але, оскільки наша фабрика - конкретна (а не абстрактна), і ми знаємо про всі типи її продукції, то ми безумовно зможемо дізнатися максимальний розмір об'єкта-продукції на етапі компіляції. Наприклад, використовуючи списки типів:

//--------------------------------
//Typelist basics
//--------------------------------
template
struct Node
{
};
struct NullNode
{
};

Ми можемо написати рекурсивну compile-time функцію для обчислення максимального розміру об'єкта, з числа типів, що перебувають у списку:

template
struct GetMaxSize
{
};
template
struct GetMaxSize

Опубліковано: 05/10/11 @ 02:38
Розділ seo

Рекомендуємо:

E-commerce конференція «Бізнес інтернет-магазинів» 3 листопада в Києві
Інтерв'ю - Сергій Количев, автор блога max1net.com
Як повідомити Google про нові зовнішні посилання на ваш сайт
26-й - піврічний випуск подкасту «Відверто про IT кар'єризм». Бесіда з Java архітектором, екстремальним тренером і початківцям батьком Олексієм Солнцевим
Невелике summary по конференції Brand Promo