Warning: ob_start(): non-static method anchor_utils::ob_filter() should not be called statically in /home4/flguy2/public_html/kelleyconcrete.com/wp-content/plugins/sem-external-links/anchor-utils/anchor-utils.php on line 33
Get Adobe Flash player
Calendar
January 2018
M T W T F S S
« Dec    
1234567
891011121314
15161718192021
22232425262728
293031  

Knuth Concrete

knuth concrete

Low Session optimizing the use of memory in C + + programs with total exposure

It should be clear that all methods described in this article should be used very carefully and only in exceptional cases: usually have to pay for all the elements of low-level optimization was used for the flexibility, portability, scalability, clarity or the resulting application.

But if you have exactly that particular case and have no way back – that you're welcome.

Author:
Victor Milokum,
Apriorit team leader, network security management.

Table of Contents

  1. The optimization of the factories "Concrete" (variations on Pimple language)
  2. Optimization for "Arena"

"In computing, optimization is the process of modifying a system to to some aspect of it work more efficiently or use fewer resources. The system can be a single computer program, a set of equipment or even an entire network such as the Internet.
Although the word "optimization" shares the same root as "the best", it is rare that the optimization process to produce a truly optimal. Often there is no "one size fits all" design that works well in all cases, so the engineers to make concessions to optimize the attributes of interest.
Donald Knuth made the following statement on the optimization: "We should forget about efficiency small, for example about 97% of the time: premature optimization is the root of all evil. "An alternative approach is the first code design, since the design and profile / benchmark the resulting code to see which parts should be optimized. "

(C) wiki

Optimization Concrete factory "in GoF. terminology:

struct IObject
(
IObject virtual ~ () ()
virtual void DoIt () = 0;
);
CFactory class
(
public:
CreateSmth empty (objtype int, std:: auto_ptr <IObject> * pResult)
(
if (iValue <0)
(
return pResult-> (new CObject1)
)
more
(
return pResult-> (CObject2 new);
)
)
);

This model is ideal for avoiding endless, whether through more switch'es the code, but has one drawback unpleasant. It has to do with the excessive use of dynamic memory that sometimes seriously affects C + + implementation of programs. We will try to cure this patter that – with

std:: auto_ptr <IObject> product;

We define a set of containers for the production, where the created object is stored.

MySuperFactory.CreateSmth (1, and the product);

We create an object in this container through the factory.

product-> DoIt (); operator – new location – to create new objects in the custom "row" buffer. For example:

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

It is very useful considering the fact that we can assign the most effective buffer that the application new standard does. But in reality the use of the new deployment also adds some difficulties for the life of the developer:

  • row buffer must be aligned by the range depends on the platform;
  • The destructor of the object created must be applied manually.
  • Stack is the great alternative for the stack. It would be tempting to use buffer on the stack as the container, ie to use
    IObject> <ObjectSize, MyWrapperAroundLocalBuffer product; For example, we use lists of type:

//——————————–
/ / Basics typelist
//——————————–
Tail> Head, <class template class
struct Node
(
);
struct NullNode
(
);

We can develop the recursive function at compile time to calculate the maximum size of the object types listed:

<List template <class
struct GetMaxSize
(
);
Tail> Head, <class template class
struct GetMaxSize <Node <Head, Tail>>
(
static const size_t TailSize = GetMaxSize <Tail>:: Result;
static const size_t result = (TailSize> sizeof (head))
? TailSize: sizeof (Chief);
);
template> <
struct GetMaxSize <NullNode>
(
static const size_t Result = 0;
); As for our container must be able to store objects of different types that we have a right to expect any help from them in the form of interface support for:

struct iManager
(
iManager virtual ~ () ()
DestroyObject virtual void (void * pObject) = 0;
CreateAndSwap virtual void (Void * pObject, int iMaxSize) = 0;
CreateAndCopy virtual void (void * pObject, int iMaxSize) = 0;
);

That is, an object that wants to live our container should be able to:

    • Destroy the objects of its kind for a specified address;
    • Use technology Create and exchange to move the object property (optional)
    • Use technology to create and copy objects to create a copy (optional).
  • different virtual bases of objects placed in the buffer of rows:

    • Pointer to iManager to manage the lifecycle of objects;
    • Pointer

      / / Indicators of manageable control (field iFlags)
      allow_std_swap const int = 1;
      const int allow_copy = 2;
      const allow_all int = 3;

      / / Class manageable: wrapper, provides a binary interface for managing the object lifetime
      <class template ImplType, iFlags> int
      manageable class: public iManager, public ImplType
      (
      typedef <ImplType, iFlags> ThisType manageable;

      DestroyObject virtual void ");
      )

      template> <
      <allow_std_swap> CreateAndSwapImpl empty (void * pObject, int / * iMaxSize * /)
      (
      ThisType pNewObject * = new (pObject) ThisType ();
      pNewObject swap-> (* this);
      )

      virtual void CreateAndSwap (pObject void *, Int iMaxSize)
      (
      if (sizeof (ThisType)> iMaxSize)
      throw std:: runtime_error ("Object too large, the method of exchange no ");
      <iFlags CreateAndSwapImpl &> Allow_std_swap (pObject, iMaxSize)
      )

      / / CreateAndCopy
      iFlags template> <Int
      CreateAndCopyImpl void (void * / * pObject * /, int / * iMaxSize * /)
      (
      throw std:: runtime_error ("Copy method is not supported ");
      )
      template> <
      <allow_copy> CreateAndCopyImpl empty (void * PObject, int / * iMaxSize * /) : ImplType (param0)
      (
      )
      );

      The pattern is parameterized by object type and flags that define what methods should be follows:

      CFastConcreteFactory class
      (
      public:
      typedef utils: utils Node <:: utils::> <CObject1, allow_copy manageable,
      utils:: Node utils <:: manageable utils:: allow_copy> <CObject2,,
      utils:: NullNode
      >
      > ObjectList;

      <CObject1,
      utils:: >()); allow_copy
      )
      more
      (
      pResult-> CreateByCopy (utils:: CObject2 <manageable
      CFastConcreteFactory factory
      CFastConcreteFactory:: AnyObject product;
      factory.CreateSmth (-1, and product);
      product-> DoIt ();
      / / Copy sample
      CFastConcreteFactory:: another_product AnyObject;
      product.Copy (Y another_product)

      But the functioning of our creation will be much faster (fast_object_sample see attachments).

      All source code, examples, performance and unit testing can be found in the library
      MakeItFaster in the documents. There are also projects for VC + + 7.1 and VC + + 8.0.

      View: cmnFastObjects.h, its implementation is a bit smaller.

      Imagine you have some iterative algorithm is repeated N times the action:

      mega_algorithm int (int N)
      (
      int count = 0;
      for (int i = 0; i N <; + + i)
      (
      Count + = DoSmth1 ();
      )
      Count return;
      )

      Suppose that two conditions are met:

Comments are closed.