C ++ рдореЗрдВ рдореЗрдореЛрд░реА рдореИрдиреЗрдЬрдореЗрдВрдЯ

рдбрд╛рдпрдиреЗрдорд┐рдХ рдореЗрдореЛрд░реА рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдЕрдХреНрд╕рд░ рдХрдИ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдореЗрдВ рдПрдХ рдЕрдбрд╝рдЪрди рд╣реИ рдпрджрд┐ рдЖрдк рд╡рд┐рд╢реЗрд╖ рдЯреНрд░рд┐рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред

рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рдРрд╕реА рдХреБрдЫ рддрдХрдиреАрдХреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реВрдВрдЧрд╛ред рд▓реЗрдЦ рдореЗрдВ рдЙрджрд╛рд╣рд░рдг рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╣реИрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЗрд╕рдореЗрдВ рд╕реЗ) рд╡реЗ рдирдП рдФрд░ рдЕрдзрд┐рднрд╛рд░ рд╕рдВрдЪрд╛рд▓рдХреЛрдВ рдХреЛ рдЕрдзрд┐рднрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕рдХреЗ рдХрд╛рд░рдг, рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдирд┐рд░реНрдорд╛рдг рдиреНрдпреВрдирддрд░ рд╣реЛрдВрдЧреЗ, рдФрд░ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛ рдкрд░рд┐рд╡рд░реНрддрди рд╕рд░рд▓ рд╣реЛрдЧрд╛ред рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдкрд╛рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдиреБрдХрд╕рд╛рди рднреА рд╡рд░реНрдгрд┐рдд рд╣реИрдВ (рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдЧреБрд░реБ рдЬреЛ рдорд╛рдирдХ рдХреЛ рдХрд╡рд░ рд╕реЗ рдХрд╡рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрдврд╝рддреЗ рд╣реИрдВ, рд╡реЗ рдЖрд╢реНрдЪрд░реНрдпрдЪрдХрд┐рдд рдирд╣реАрдВ рд╣реЛрдВрдЧреЗ)ред



0. рдХреНрдпрд╛ рд╣рдореЗрдВ рдореЗрдореЛрд░реА рдХреЗ рд╕рд╛рде рдореИрдиреБрдЕрд▓ рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ?


рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдЬрд╛рдВрдЪ рдХрд░реЗрдВрдЧреЗ рдХрд┐ рдПрдХ рдЖрд╡рдВрдЯрдирдХрд░реНрддрд╛ рд╕реНрдорд╛рд░реНрдЯ рдХреИрд╕реЗ рдореЗрдореЛрд░реА рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХреЛ рдЧрддрд┐ рджреЗ рд╕рдХрддрд╛ рд╣реИред

рд╣рдо C ++ рдФрд░ C # рдХреЗ рд▓рд┐рдП рд╕рд░рд▓ рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦреЗрдВрдЧреЗ (C # рдЕрдкрдиреЗ рдЙрддреНрдХреГрд╖реНрдЯ рдореЗрдореЛрд░реА рдореИрдиреЗрдЬрд░ рдХреЗ рд▓рд┐рдП рдЬрд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдкреАрдврд╝реА рджреНрд╡рд╛рд░рд╛ рд╡рд╕реНрддреБрдУрдВ рдХреЛ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рддрд╛ рд╣реИ, рд╡рд┐рднрд┐рдиреНрди рдЖрдХрд╛рд░реЛрдВ рдХреА рд╡рд╕реНрддреБрдУрдВ рдХреЗ рд▓рд┐рдП рд╡рд┐рднрд┐рдиреНрди рдкреВрд▓реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдЖрджрд┐)ред

class Node { public: Node* next; }; // ... for (int i = 0; i < 10000000; i++) { Node* v = new Node(); } 


 class Node { public Node next; } // ... for (int l = 0; l < 10000000; l++) { var v = new Node(); } 


рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рднреА "рдЧреЛрд▓рд╛рдХрд╛рд░ рд╡реИрдХреНрдпреВрдо" рдХреЗ рдмрд╛рд╡рдЬреВрдж, рд╕рдордп рдХрд╛ рдЕрдВрддрд░ 10 рдЧреБрдирд╛ (62 рдПрдордПрд╕ рдмрдирд╛рдо 650 рдПрдордПрд╕) рд╣реЛ рдЧрдпрд╛ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╕реА # рдЙрджрд╛рд╣рд░рдг рд╕рдорд╛рдкреНрдд рд╣реЛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рд╕реА ++ рдореЗрдВ рдЕрдЪреНрдЫреЗ рдЯреЛрди рдХреЗ рдирд┐рдпрдореЛрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░, рдЪрдпрдирд┐рдд рд╡рд╕реНрддреБрдУрдВ рдХреЛ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЬреЛ рдЕрдВрддрд░рд╛рд▓ (2580 рдПрдордПрд╕ рддрдХ) рдХреЛ рдФрд░ рдмрдврд╝рд╛ рджреЗрдЧрд╛ред

1. рдСрдмреНрдЬреЗрдХреНрдЯ рдкреВрд▓


рд╕реНрдкрд╖реНрдЯ рд╕рдорд╛рдзрд╛рди рдУрдПрд╕ рд╕реЗ рдореЗрдореЛрд░реА рдХрд╛ рдПрдХ рдмрдбрд╝рд╛ рдмреНрд▓реЙрдХ рд▓реЗрдирд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдмрд░рд╛рдмрд░ рдЖрдХрд╛рд░ рдХреЗ (рдиреЛрдб) рдмреНрд▓реЙрдХ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдирд╛ рд╣реИ, рдЬрдм рдореЗрдореЛрд░реА рдЖрд╡рдВрдЯрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдкреВрд▓ рд╕реЗ рдПрдХ рдмреНрд▓реЙрдХ рд▓реЗрддреЗ рд╣реИрдВ, рдФрд░ рдореБрдХреНрдд рд╣реЛрдиреЗ рдкрд░, рдЗрд╕реЗ рдкреВрд▓ рдореЗрдВ рд▓реМрдЯрд╛рддреЗ рд╣реИрдВред рдкреВрд▓ рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рдПрдХ рдПрдХрд▓ рд▓рд┐рдВрдХ рдХреА рдЧрдИ рд╕реВрдЪреА (рд╕реНрдЯреИрдХ) рдХреЗ рд╕рд╛рде рд╣реИред

рдЪреВрдВрдХрд┐ рдХрд╛рд░реНрдпрдХреНрд░рдо рдореЗрдВ рдиреНрдпреВрдирддрдо рд╣рд╕реНрддрдХреНрд╖реЗрдк рдХрд╛ рдХрд╛рд░реНрдп рд╣реЛрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рд╕рдм рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдмреНрд▓реЙрдХрдСрд▓реЛрдХ рдХрд╛ рдПрдХ рдЬреЛрдбрд╝рд╛ рдиреЛрдб рд╡рд░реНрдЧ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдП:
 class Node : public BlockAlloc<Node> 


рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдореЗрдВ рдмрдбрд╝реЗ рдмреНрд▓реЙрдХреЛрдВ (рдкреГрд╖реНрдареЛрдВ) рдХрд╛ рдПрдХ рдкреВрд▓ рдЪрд╛рд╣рд┐рдП, рдЬрд┐рд╕реЗ рд╣рдо рдУрдПрд╕ рдпрд╛ рд╕реА-рд░рдирдЯрд╛рдЗрдо рд╕реЗ рджреВрд░ рд▓реЗ рдЬрд╛рддреЗ рд╣реИрдВред рдпрд╣ рдореЙрд▓реЛрдХ рдФрд░ рдореБрдХреНрдд рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ рдЖрдпреЛрдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдзрд┐рдХ рджрдХреНрд╖рддрд╛ (рдЕрдореВрд░реНрддрддрд╛ рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рд╕реНрддрд░ рдХреЛ рдЫреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП) рдХреЗ рд▓рд┐рдП, рд╣рдо VirtualAlloc / VirtualFree рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдпреЗ рдлрд╝рдВрдХреНрд╢рди рдЙрди рдмреНрд▓реЙрдХреЛрдВ рдореЗрдВ рдореЗрдореЛрд░реА рдЖрд╡рдВрдЯрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ 4K рдХреЗ рдЧреБрдгрдХ рд╣реИрдВ, рдФрд░ 64K рдХреЗ рдЧреБрдгрдХреЛрдВ рд╡рд╛рд▓реЗ рдмреНрд▓реЙрдХреЛрдВ рдореЗрдВ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдкрддрд╛ рд╕реНрдерд╛рди рдХреЛ рднреА рдЖрд░рдХреНрд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдкреНрд░рддрд┐рдмрджреНрдз рдФрд░ рдЖрд░рдХреНрд╖рд┐рдд рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдХреЗ, рд╣рдо рдЕрдореВрд░реНрддрддрд╛ рдХреЗ рдПрдХ рдФрд░ рд╕реНрддрд░ рдХреЛ рдЫреЛрдбрд╝рддреЗ рд╣реИрдВ, рдкрддреЗ рдХреА рдЬрдЧрд╣ рдХреЛ рдЬрдорд╛ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдПрдХ рдХреЙрд▓ рдХреЗ рд╕рд╛рде рдореЗрдореЛрд░реА рдкреЗрдЬ рдЖрд╡рдВрдЯрд┐рдд рдХрд░рддреЗ рд╣реИрдВред

рдкреЗрдЬрдкреВрд▓ рдХреНрд▓рд╛рд╕
 inline size_t align(size_t x, size_t a) { return ((x-1) | (a-1)) + 1; } //#define align(x, a) ((((x)-1) | ((a)-1)) + 1) template<size_t PageSize = 65536> class PagePool { public: void* GetPage() { void* page = VirtualAlloc(NULL, PageSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); pages.push_back(page); return page; } ~PagePool() { for (vector<void*>::iterator i = pages.begin(); i != pages.end(); ++i) { VirtualFree(*i, 0, MEM_RELEASE); } } private: vector<void*> pages; }; 


рдлрд┐рд░ рд╣рдо рджрд┐рдП рдЧрдП рдЖрдХрд╛рд░ рдХреЗ рдмреНрд▓реЙрдХреЛрдВ рдХрд╛ рдПрдХ рдкреВрд▓ рдмрдирд╛рддреЗ рд╣реИрдВ

рдХрдХреНрд╖рд╛ рдЕрд╡рд░реЛрдзрдХ
 template<class T, size_t PageSize = 65536, size_t Alignment = 8 /* sizeof(void*) */> class BlockPool : PagePool<PageSize> { public: BlockPool() : head(NULL) { BlockSize = align(sizeof(T), Alignment); count = PageSize / BlockSize; } void* AllocBlock() { // todo: lock(this) if (!head) FormatNewPage(); void* tmp = head; head = *(void**)head; return tmp; } void FreeBlock(void* tmp) { // todo: lock(this) *(void**)tmp = head; head = tmp; } private: void* head; size_t BlockSize; size_t count; void FormatNewPage() { void* tmp = GetPage(); head = tmp; for(size_t i = 0; i < count-1; i++) { void* next = (char*)tmp + BlockSize; *(void**)tmp = next; tmp = next; } *(void**)tmp = NULL; } }; 


рдЯрд┐рдкреНрдкрдгреА // рдЯреВрдбреВ: рд▓реЙрдХ (рдпрд╣) рдЙрди рд╕реНрдерд╛рдиреЛрдВ рдХреЛ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬрд┐рдирдХреЗ рд▓рд┐рдП рдХреНрд░реЙрд╕-рдереНрд░реЗрдб рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, EnterCriticalSection рдпрд╛ рдмрдврд╝рд╛рд╡рд╛ :: mutex рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ)ред

рдореИрдВ рд╕рдордЭрд╛рддрд╛ рд╣реВрдВ рдХрд┐ рдкреГрд╖реНрда рдХрд╛ "рд╕реНрд╡рд░реВрдкрдг" рдкреВрд▓ рдореЗрдВ рдмреНрд▓реЙрдХ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдлреНрд░реАрдмреНрд▓реЙрдХ рдПрдмреНрд╕реНрдЯреНрд░реИрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреНрдпреЛрдВ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдЕрдЧрд░ рдХреБрдЫ рдкрд╕рдВрдж рд╣реИ

 for (size_t i = 0; i < PageSize; i += BlockSize) FreeBlock((char*)tmp+i); 


FIFO рд╕рд┐рджреНрдзрд╛рдВрдд рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЙрд╕ рдкреГрд╖реНрда рдХреЛ "рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд" рдЪрд┐рд╣реНрдирд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛:


рдПрдХ рдкрдВрдХреНрддрд┐ рдореЗрдВ рдкреВрд▓ рд╕реЗ рдЕрдиреБрд░реЛрдз рдХрд┐рдП рдЧрдП рдХрдИ рдмреНрд▓реЙрдХ рдШрдЯрддреЗ рдкрддреЗ рд╣реЛрдВрдЧреЗред рдФрд░ рдкреНрд░реЛрд╕реЗрд╕рд░ рд╡рд╛рдкрд╕ рдЬрд╛рдирд╛ рдкрд╕рдВрдж рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд╕реЗ рд╡рд╣ рдкреНрд░реАрдлрдЪ ( UPD : рдЖрдзреБрдирд┐рдХ рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдирд╣реАрдВ) рдЯреВрдЯ рдЬрд╛рддрд╛ рд╣реИред рдпрджрд┐ рдЖрдк рдорд╛рд░реНрдХрдЕрдк рдХреЛ рд▓реВрдк рдореЗрдВ рдХрд░рддреЗ рд╣реИрдВ
 for (size_t i = PageSize-(BlockSize-(PageSize%BlockSize)); i != 0; i -= BlockSize) FreeBlock... 

рддрдм рдорд╛рд░реНрдХрдЕрдк рд▓реВрдк рд╡рд╛рдкрд╕ рдкрддреЛрдВ рдкрд░ рдЬрд╛рдПрдЧрд╛ред

рдЕрдм рдЬрдм рддреИрдпрд╛рд░реА рдХреА рдЬрд╛рддреА рд╣реИ, рддреЛ рд╣рдо рдЕрд╢реБрджреНрдзрддрд╛ рд╡рд░реНрдЧ рдХрд╛ рд╡рд░реНрдгрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
 template<class T> class BlockAlloc { public: static void* operator new(size_t s) { if (s != sizeof(T)) { return ::operator new(s); } return pool.AllocBlock(); } static void operator delete(void* m, size_t s) { if (s != sizeof(T)) { ::operator delete(m); } else if (m != NULL) { pool.FreeBlock(m); } } // todo: implement nothrow_t overloads, according to borisko' comment // http://habrahabr.ru/post/148657/#comment_5020297 // Avoid hiding placement new that's needed by the stl containers... static void* operator new(size_t, void* m) { return m; } // ...and the warning about missing placement delete... static void operator delete(void*, void*) { } private: static BlockPool<T> pool; }; template<class T> BlockPool<T> BlockAlloc<T>::pool; 


рдореИрдВ рд╕рдордЭрд╛рдКрдВрдЧрд╛ рдХрд┐ рдХреНрдпреЛрдВ (s! = Sizeof (T)) рдЪреЗрдХ рдХреА рдЬрд░реВрд░рдд рд╣реИ
рд╡реЗ рдХрдм рдЖрдЧ рд▓рдЧрд╛рддреЗ рд╣реИрдВ? рддрдм, рдЬрдм рдЖрдзрд╛рд░ T рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓реА рдПрдХ рдХреНрд▓рд╛рд╕ рдмрдирд╛рдИ / рдбрд┐рд▓реАрдЯ рдХреА рдЬрд╛рддреА рд╣реИред
рд╡рд╛рд░рд┐рд╕ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдирдП / рдбрд┐рд▓реАрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ, рд▓реЗрдХрд┐рди рдЙрдирдореЗрдВ рдмреНрд▓реЙрдХрдСрд▓реЛрдХ рдХреЛ рднреА рдЬреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдо рдЖрд╕рд╛рдиреА рд╕реЗ рдФрд░ рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдХрд╛рд░реНрдпрдХреНрд░рдо рдореЗрдВ рдХреБрдЫ рддреЛрдбрд╝рдиреЗ рдХреЗ рдбрд░ рдХреЗ рдмрд┐рдирд╛ рдХрд┐рди рд╡рд░реНрдЧреЛрдВ рдХреЛ рдкреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдорд▓реНрдЯреАрдкрд▓ рдЗрдирд╣реЗрд░рд┐рдЯреЗрдВрд╕ рднреА рдЗрд╕ рдкреНрд░рд╡реЗрд╢ рдХреЗ рд╕рд╛рде рдмрдврд╝рд┐рдпрд╛ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

рд╣реЛ рдЧрдпрд╛ред BlockAlloc Node рдФрд░ retest рдХреЛ рдЗрдирд╣реЗрд░рд┐рдЯ рдХрд░реЗрдВред
рдкрд░реАрдХреНрд╖рд╛ рдХрд╛ рд╕рдордп рдЕрдм тАЛтАЛ120 рдорд┐ред 5 рдмрд╛рд░ рддреЗрдЬреА рд╕реЗред рд▓реЗрдХрд┐рди рд╕реА # рдореЗрдВ, рдПрдХ рдЖрд╡рдВрдЯрдирдХрд░реНрддрд╛ рдЕрднреА рднреА рдмреЗрд╣рддрд░ рд╣реИред рд╕рдВрднрд╡рддрдГ рдПрдХ рд▓рд┐рдВрдХ рдХреА рдЧрдИ рд╕реВрдЪреА рдирд╣реАрдВ рд╣реИред (рдпрджрд┐ рд╣рдо рдирдП рдХреЗ рддреБрд░рдВрдд рдмрд╛рдж рдбрд┐рд▓реАрдЯ рдХреЛ рддреБрд░рдВрдд рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЗрд╕ рддрд░рд╣ рдХреИрд╢ рдореЗрдВ рдбреЗрдЯрд╛ рдбрд╛рд▓рдиреЗ рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдореЗрдореЛрд░реА рдмрд░реНрдмрд╛рдж рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ 62 рдПрдордПрд╕ рдорд┐рд▓реЗрдВрдЧреЗред рдЕрдЬреАрдмред .NET рд╕реАрдПрд▓рдЖрд░ рдХреА рддрд░рд╣, рдЬреИрд╕реЗ рдХрд┐ рдпрд╣ рдлреНрд░реА-рдЕрдк рд▓реЛрдХрд▓ рд╡реИрд░рд┐рдПрдмрд▓реНрд╕ рдХреЛ рддреБрд░рдВрдд рд╕рдВрдмрдВрдзрд┐рдд рдкреВрд▓ рдореЗрдВ рд▓реМрдЯрд╛рддрд╛ рд╣реИ, рдЬреАрд╕реА рдХреЗ рдЗрдВрддрдЬрд╛рд░ рдХреЗ рдмрд┐рдирд╛)

2. рдХрдВрдЯреЗрдирд░ рдФрд░ рдЙрд╕рдХреЗ рд░рдВрдЧреАрди рд╕рд╛рдордЧреНрд░реА



рдХреНрдпрд╛ рдЖрдк рдЕрдХреНрд╕рд░ рдЙрди рдХрдХреНрд╖рд╛рдУрдВ рдореЗрдВ рдЖрддреЗ рд╣реИрдВ рдЬреЛ рдЕрдкрдиреЗ рдЖрдк рдореЗрдВ рдмрд╣реБрдд рд╕реА рдЕрд▓рдЧ-рдЕрд▓рдЧ рдмрд╛рд▓ рд╡рд╕реНрддреБрдУрдВ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддреЗ рд╣реИрдВ, рдЬреИрд╕реЗ рдХрд┐ рдЙрддреНрддрд░рд╛рд░реНрджреНрдз рдХрд╛ рдЬреАрд╡рдирдХрд╛рд▓ рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХреЗ рдЬреАрд╡рдирдХрд╛рд▓ рд╕реЗ рдЕрдзрд┐рдХ рд▓рдВрдмрд╛ рдирд╣реАрдВ рд╣реИ?

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣ рдПрдХ XmlDocument рд╡рд░реНрдЧ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдиреЛрдб рдФрд░ рдЧреБрдг рд╡рд░реНрдЧреЛрдВ рд╕реЗ рднрд░рд╛ рд╣реЛрддрд╛ рд╣реИ, рд╕рд╛рде рд╣реА рдиреЛрдбреНрд╕ рдХреЗ рдЕрдВрджрд░ рдкрд╛рда рд╕реЗ рд▓реА рдЧрдИ рд╕реА-рд▓рд╛рдЗрдиреНрд╕ (рдЪрд╛рд░ *) рднреА рд╣реЛрддреА рд╣реИред рдпрд╛ рдлрд╝рд╛рдЗрд▓ рдкреНрд░рдмрдВрдзрдХ рдореЗрдВ рдлрд╝рд╛рдЗрд▓реЛрдВ рдФрд░ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдУрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдЬреЛ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрдврд╝рдиреЗ рдФрд░ рдЕрдм рдмрджрд▓рдиреЗ рдкрд░ рд▓реЛрдб рд╣реЛрддреА рд╣реИред

рдЬреИрд╕рд╛ рдХрд┐ рдкрд░рд┐рдЪрдп рдореЗрдВ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд╣рдЯрд╛рдирд╛ рдирдП рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рдорд╣рдВрдЧрд╛ рд╣реИред рд▓реЗрдЦ рдХреЗ рджреВрд╕рд░реЗ рднрд╛рдЧ рдХрд╛ рд╡рд┐рдЪрд╛рд░ рдкреЗрд░реЗрдВрдЯ рдСрдмреНрдЬреЗрдХреНрдЯ рд╕реЗ рдЬреБрдбрд╝реЗ рдПрдХ рдмрдбрд╝реЗ рдмреНрд▓реЙрдХ рдореЗрдВ рдмрд╛рд▓ рд╡рд╕реНрддреБрдУрдВ рдХреЗ рд▓рд┐рдП рдореЗрдореЛрд░реА рдЖрд╡рдВрдЯрд┐рдд рдХрд░рдирд╛ рд╣реИред рдЬрдм рдореВрд▓ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдмрдЪреНрдЪреЗ рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣, рд╡рд┐рдирд╛рд╢рдХреЛрдВ рдХреЛ рдмреБрд▓рд╛рдПрдВрдЧреЗ, рд▓реЗрдХрд┐рди рдЙрдиреНрд╣реЗрдВ рдореЗрдореЛрд░реА рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрдЧреА - рдпрд╣ рдПрдХ рдмрдбрд╝реЗ рдмреНрд▓реЙрдХ рдХреЗ рд╕рд╛рде рдореБрдХреНрдд рд╣реЛ рдЬрд╛рдПрдЧрд╛ред

рдЖрдЗрдП PointerBumpAllocator рдХреНрд▓рд╛рд╕ рдмрдирд╛рдПрдВ, рдЬреЛ рдПрдХ рдмрдбрд╝реЗ рдмреНрд▓реЙрдХ рд╕реЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЖрдХрд╛рд░ рдХреЗ рдЯреБрдХрдбрд╝реЗ рдХрд╛рдЯ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдкреБрд░рд╛рдиреЗ рдХреЗ рд╕рдорд╛рдкреНрдд рд╣реЛрдиреЗ рдкрд░ рдПрдХ рдирдпрд╛ рдмрдбрд╝рд╛ рдмреНрд▓реЙрдХ рдЖрд╡рдВрдЯрд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИред

PointerBumpAllocator рд╡рд░реНрдЧ
 template<size_t PageSize = 65536, size_t Alignment = 8 /* sizeof(void*) */> class PointerBumpAllocator { public: PointerBumpAllocator() : free(0) { } void* AllocBlock(size_t block) { // todo: lock(this) block = align(block, Alignment); if (block > free) { free = align(block, PageSize); head = GetPage(free); } void* tmp = head; head = (char*)head + block; free -= block; return tmp; } ~PointerBumpAllocator() { for (vector<void*>::iterator i = pages.begin(); i != pages.end(); ++i) { VirtualFree(*i, 0, MEM_RELEASE); } } private: void* GetPage(size_t size) { void* page = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); pages.push_back(page); return page; } vector<void*> pages; void* head; size_t free; }; typedef PointerBumpAllocator<> DefaultAllocator; 


рдЕрдВрдд рдореЗрдВ, рд╣рдо рдУрд╡рд░рд▓реЛрдб рдирдП рдХреЗ рд╕рд╛рде рдЪрд╛рдЗрд▓реНрдбрдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдПрдХ рдкреНрд░рд╡реЗрд╢ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рджрд┐рдП рдЧрдП рдЖрд╡рдВрдЯрди рдХреЛ рдПрдХреНрд╕реЗрд╕ рдХрд░рддреЗ рд╣реБрдП рд╣рдЯрд╛рддреЗ рд╣реИрдВ:

 template<class T, class A = DefaultAllocator> struct ChildObject { static void* operator new(size_t s, A& allocator) { return allocator.AllocBlock(s); } static void* operator new(size_t s, A* allocator) { return allocator->AllocBlock(s); } static void operator delete(void*, size_t) { } // *1 static void operator delete(void*, A*) { } static void operator delete(void*, A&) { } private: static void* operator new(size_t s); }; 


рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдмрдЪреНрдЪреЗ рдХреА рдХрдХреНрд╖рд╛ рдореЗрдВ рдПрдХ рдЕрд╢реБрджреНрдзрддрд╛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╕рднреА рдХреЙрд▓ рдХреЛ рдирдП (рдпрд╛ "рдХрд╛рд░рдЦрд╛рдиреЗ" рдкреИрдЯрд░реНрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛) рд╕рд╣реА рдХрд░рдирд╛ рднреА рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛ред рдирдП рдСрдкрд░реЗрдЯрд░ рдХреЗ рд▓рд┐рдП рд╕рд┐рдВрдЯреИрдХреНрд╕ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реЛрдЧрд╛:

рдирдпрд╛ (... рдСрдкрд░реЗрдЯрд░ рдХреЗ рд▓рд┐рдП рдкреИрд░рд╛рдореАрдЯрд░ ...) рдЪрд╛рдЗрд▓реНрдбрдСрдмрдЬреЗрдХреНрдЯ (... рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдкреИрд░рд╛рдореАрдЯрд░ ...)

рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рджреЛ рдирдП рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЬреЛ A & A * рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВред
рдпрджрд┐ рдПрдХ рдЖрд╡рдВрдЯрдирдХрд░реНрддрд╛ рдХреЛ рд╕рджрд╕реНрдп рдХреЗ рд░реВрдк рдореЗрдВ рдореВрд▓ рд╡рд░реНрдЧ рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдкрд╣рд▓рд╛ рд╡рд┐рдХрд▓реНрдк рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реЛрддрд╛ рд╣реИ:
 node = new(allocator) XmlNode(nodename); 

рдпрджрд┐ рдПрдХ рдЖрд╡рдВрдЯрдирдХрд░реНрддрд╛ рдХреЛ рдкреВрд░реНрд╡рдЬ (рдЕрд╢реБрджреНрдзрддрд╛) рдХреЗ рд░реВрдк рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рджреВрд╕рд░рд╛ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реЛрддрд╛ рд╣реИ:
 node = new(this) XmlNode(nodename); 


рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рд╕реВрдЪрдХ рдФрд░ рд▓рд┐рдВрдХ рдкрд╛рд░рд╕реНрдкрд░рд┐рдХ рд░реВрдк рд╕реЗ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рд╣реЛ рдЧрдП рд╣реИрдВ, рдЗрди рдорд╛рдорд▓реЛрдВ рдХреА рдЬреБрджрд╛рдИ - рдЕрддрд┐рд░рд┐рдХреНрдд рдЖрдЗрдХрди рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛ рд░рд╣реЗ рд╣реИрдВред

рдХреЙрд▓ рд╣рдЯрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рд╡рд┐рд╢реЗрд╖ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдирд╣реАрдВ рд╣реИ; рд╕рдВрдХрд▓рдХ рдорд╛рдирдХ рдбрд┐рд▓реАрдЯ (* 1 рдЪрд┐рд╣реНрдирд┐рдд) рдХреЛ рдХреЙрд▓ рдХрд░реЗрдЧрд╛, рднрд▓реЗ рд╣реА рдирдП рдСрдкрд░реЗрдЯрд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдЕрд░реНрдерд╛рдд, рдбрд┐рд▓реАрдЯ рд╕рд┐рдВрдЯреИрдХреНрд╕ рд╕рд╛рдорд╛рдиреНрдп рд╣реИ:
 delete node; 


рдпрджрд┐ рдЪрд╛рдЗрд▓реНрдбрдСрдмрдЬреЗрдХреНрдЯ (рдпрд╛ рдЙрд╕рдХреЗ рдЙрддреНрддрд░рд╛рдзрд┐рдХрд╛рд░реА) рдХреЗ рдирд┐рд░реНрдорд╛рдг рдореЗрдВ рдХреЛрдИ рдЕрдкрд╡рд╛рдж рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдЗрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛ рдмрдирд╛рддреЗ рд╕рдордп рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдирдП рдСрдкрд░реЗрдЯрд░ рдХреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЗ рдЕрдиреБрд░реВрдк рд╣рдЯрд╛рдПрдВ рдХреЛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ (рдкрд╣рд▓реЗ рдкреИрд░рд╛рдореАрдЯрд░ size_t рдХреЛ void * рдХреЗ рд╕рд╛рде рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛)ред

рдирдП рдСрдкрд░реЗрдЯрд░ рдХреЛ рдирд┐рдЬреА рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рд░рдЦрдиреЗ рд╕реЗ рдЖрд╡рдВрдЯрдирдХрд░реНрддрд╛ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдП рдмрд┐рдирд╛ рдирдП рдХреЙрд▓ рдХрд░рдиреЗ рд╕реЗ рдмрдЪрд╛рддрд╛ рд╣реИред

рдпрд╣рд╛рдВ рдПрд▓реЛрдХреЗрдЯрд░-рдЪрд╛рдЗрд▓реНрдбрдСрдмреНрдЬреЗрдХреНрдЯ рдЬреЛрдбрд╝реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдкреВрд░рд╛ рдЙрджрд╛рд╣рд░рдг рд╣реИ:
рдЙрджрд╛рд╣рд░рдг
 class XmlDocument : public DefaultAllocator { public: ~XmlDocument() { for (vector<XmlNode*>::iterator i = nodes.begin(); i != nodes.end(); ++i) { delete (*i); } } void AddNode(char* content, char* name) { char* c = (char*)AllocBlock(strlen(content)+1); strcpy(c, content); char* n = (char*)AllocBlock(strlen(name)+1); strcpy(n, content); nodes.push_back(new(this) XmlNode(c, n)); } class XmlNode : public ChildObject<XmlNode, XmlDocument> { public: XmlNode(char* _content, char* _name) : content(_content), name(_name) { } private: char* content; char* name; }; private: vector<XmlNode*> nodes; }; 


рдирд┐рд╖реНрдХрд░реНрд╖ред рд╕реИрдВрдбрдмреЙрдХреНрд╕ рдХреЗ рд▓рд┐рдП рд▓реЗрдЦ 1.5 рд╕рд╛рд▓ рдкрд╣рд▓реЗ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдЕрдлрд╕реЛрд╕, рдореЙрдбрд░реЗрдЯрд░ рдХреЛ рдпрд╣ рдкрд╕рдВрдж рдирд╣реАрдВ рдЖрдпрд╛ред

Source: https://habr.com/ru/post/In148657/


All Articles