|
Boost : |
Subject: Re: [boost] [devector] optimum growing/insertion policy
From: Joaquin M López Muñoz (joaquinlopezmunoz_at_[hidden])
Date: 2017-11-01 21:29:33
El 01/11/2017 a las 20:21, Thorsten Ottosen escribió:
> Den 26-10-2017 kl. 19:59 skrev Joaquin M López Muñoz via Boost:
>> El 26/10/2017 a las 17:08, Thorsten Ottosen escribió:
>>> But the policy does not know size() unless we pass it that too.
>>
>> Yes, it need access the size and front and back capacity. If the
>> policy is used via
>> CRTP (which is what I have in mind but admittedly didn't make clear)
>> then this info
>> can be retrived by the policy through devector's public interface.
>> Other designs
>> would require that the info be passed as additional arguments to the
>> member
>> functions.
>
> Regardless,
>
> We also need to see what to test. I have tried to improve the test
> measurements,
> see attached code. It tests insertion without buffer expansion.
May I suggest we use something like the following framework:
   template<typename T>
   struct default_factory
   {
     using value_type=T;
     static value_type get(){return T{};}
   };
   template<typename Factory>
   struct random_process
   {
     using factory_type=Factory;
     random_process(
       double wib,double wif,double wim,
       double web,double wef,double wem,
       const Factory& f=Factory{}):
       rnd{{wib,wif,wim,web,wef,wem}},f{f}{}
     template<typename Devector>
     void operator()(Devector& d){
       using uniform=std::uniform_int_distribution<typename
Devector::size_type>;
       switch(rnd(gen)){
         case 0: d.push_back(f.get());break;
         case 1: d.push_front(f.get());break;
         case 2:
d.insert(d.begin()+uniform{0,d.size()}(gen),f.get());break;
         case 3: if(d.size()>0)d.pop_back();break;
         case 4: if(d.size()>0)d.pop_front();break;
         case 5:
if(d.size()>0)d.erase(d.begin()+uniform{0,d.size()-1}(gen));break;
       }
     }
     std::mt19937                gen{92748}; // some arbitrary random
seed
     std::discrete_distribution<> rnd;
     Factory                     f;
   };
   template<typename RandomProcess>
   void run(RandomProcess p,int n)
   {
     boost::double_ended::devector<
       typename RandomProcess::factory_type::value_type> d;
     for(int i=0;i<n;++i)p(d);
   }
random_process models a, well, random process that, each time it is
invoked, can
do the following:
 1. push_back
 2. push_front
 3. insert at a random position within the devector
 4. pop_back
 5. pop_front
 6. erase at a random position within the devector
where each action is chosen with probabilistic weights wib, wif, wim,
web, wef
and wem, respectively. We can then easily model different usage patterns:
 * (1,0,0,0,0,0) --> growing on back
 * (1,1,0,0,0,0) --> growing both ends
 * (1,0,0,0,1,0) --> FIFO (average size = 0)
 * (2,0,0,0,1,0) --> growing FIFO
 * (0,0,1,0,0,0) --> growing, no end bias
 * (0,0,2,0,0,1) --> growing with some deletions, no end bias
Etc.
JoaquÃn M López Muñoz
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk