State data in functor members vs global function - c++

When comparing functions and functors, it is often mentioned that one advantage of a functor over a function is that a functor is statefull.
However, in this code, it seems to me that a function may be statefull too. So what I am doing/understanding wrong?
struct Accumulator
{
int counter = 0;
int operator()(int i)
{
counter += i;
return counter;
}
};
int Accumulate(int i)
{
static int counter = 0;
counter += i;
return counter;
};
int main()
{
Accumulator acc;
std::vector<int> vec{1,2,3,4};
Accumulator acc2 = std::for_each(vec.begin(), vec.end(), acc);
int d1 = acc(0); // 0, acc is passed by value
int d2 = acc2(0); // 10
std::for_each(vec.begin(), vec.end(), Accumulate);
int d4 = Accumulate(0); // 10
return 0;
}

Each instance of a functor has its own state, while the static member of a function would be shared.
If you called for_each multiple times with the Accumulate() method, the counter would never reset, and each subsequent call would begin where the previous call ended. The functor would only have this behavior if each instance was reused. Creating a new functor would solve the problem.

You've used a static local variable to store state, but there's only one copy of the state no matter how many times you use Accumulate. And as chris points out, the initialization is only ever performed once.
With the functor, each new functor instance you create has its own independent state, initialized during instance creation.
Even if you provided a reset mechanism for the function version's state (for example, by moving the variable to a helper namespace where a second function can modify it), you still have only one accumulator at a time.
With functors, you have no problem developing a rule such as "prime numbers get accumulated here, even composites there, and odd composites into a third one" that uses three accumulators at once.

Related

Memoizing based on call location

I have a member function with two arguments. Both are pointers to complex objects. When called, the function performs some non-trivial computation and then returns an integer. Like this:
struct Fooer {
int foo(const A* a, const B* b);
};
The returned integer is always the same if foo() is given the same two arguments. This function is pretty heavily used, so it would make sense to memoize its result. Normally, some lookup table with the key being the pair of pointers would suffice. However, I'm in the unique position where I know all the call sites and I know that any given call site will always use the same pair of parameters during execution. This could greatly speed up memoization if only I could pass in a third parameter, a unique integer that is basically the cache hint:
struct Fooer {
int foo(const A* a, const B* b, int pos) {
if (cached_[pos] > 0) return cached_[pos];
cached_[pos] = /* Heavy computation. */ + 1;
return cached_[pos];
}
std::vector<int> cached_;
};
What I'm looking for is a mechanism to easily generate this 'cache hint'. But nothing comes to mind. For now, I'm manually adding this parameter to the call sites of foo(), but it's obviously ugly and fragile. The function is really heavily used so it's worth this kind of optimization, in case you're wondering.
More generally, I'd like to have some kind of 'thunk' at each call site that performs the heavy lifting the first time is called, then just returns the pre-computed integer.
Note that foo() is a member function so that different instances of Fooer should have different caches.
Would this approach help you?
struct Fooer {
using CacheMap = std::map<std::pair<const A*, const B*>, int>;
std::map<int, CacheMap> lineCache;
int foo(const A* a, const B* b, int line) {
const auto key = std::make_pair(a,b);
if (linecache.count(line) > 0) {
CacheMap& cacheMap = lineCache[line];
if(cacheMap.count(key)) return cacheMap[key];
}
lineCache[line][key] = /* Heavy computation. */ + 1;
return cacheMap[key];
}
};
// Calling
foo(a, b, __LINE__)
See _ReturnAddress or any alternatives for yours compiler. Maybe you can use it in your project. Obviously, if it work for you, than just create map caller-result.

C++, different function output when called multiple times

I have the following code:
int countLatticePoints(const double radius, const int dimension) {
static std::vector<int> point {};
static int R = static_cast<int>(std::floor(radius));
static int latticePointCount = 0;
for(int i = -R; i <= R; i++) {
point.push_back(i);
if(point.size() == dimension) {
if(PointIsWithinSphere(point,R)) latticePointCount++;
} else {
countLatticePoints(R, dimension);
}
point.pop_back();
}
return latticePointCount;
}
When I make the call countLatticePoints(2.05, 3) I get the result 13 which is correct. Now I change the parameters and then call countLatticePoints(25.5, 1) I get 51 which is also correct.
Now when I call countLatticePoints(2.05, 3) and countLatticePoints(25.5, 1) right after each other in the main program I get 13 and then 18 (instead of 51), I really don't understand what i'm doing wrong ? When I call each one individually without the other I get the correct result but when I call the functions together one after the other my results change.
You're misusing static.
The second time you call the function, you push additional values into point.
Edit: I hadn't spotted the recursion. that makes things more complex, but static is still the wrong answer.
I'd create a 'state' object, and split the function into two. One that recurses, and takes a reference to the 'state' object, and a second one which initialises the state object and calls the first.
struct RecurState
{
std::vector<int> point;
int latticePointCount
RecurState() : latticePointCount(0)
{
}
}
Outer function:
int countLatticePoints(const double radius, const int dimension)
{
RecurState state;
return countLatticeRecurse(radius, dimension, state)
}
Recursive function
int countLatticeRecurse(const double radius, const int dimension, RecurseState &state)
{
...
}
Local, static variables only get initialized once, on the first function call.

c++ pass on parameter by reference to another function in a function

I am fairly new to c/c++ and I am trying to build a program for a genetic algorithm (using MS Visual Studio 2013). I will spare you the details of this program, but I do have a problem with 'passing parameters by reference'.
Can I pass on a parameter by reference to another function, inside a function? Hereunder you can find a simple example of my code.
struct solution{
int list1[100];
int list2[100];
int list3[100];
int list4[100];
};
void function1(solution& foo)
{
// Algorithm that fills list2
function2(foo); // Fills in list3
function3(foo); // Fills in list4
}
void function2(solution& foo)
{
// algorithm to fill in list3
}
void function3(solution& foo)
{
// algorithm to fill in list4
}
void localSearch(solution& foo)
{
for(int i = 0; i < 10; i++)
{
// Change a random value in list1 of foo
// Rerun function1 and see if it is a better solution
function1(foo);
}
}
int main()
{
solution bar;
// Fill list1 of bar randomly by other function
function1(bar);
// Output finished solution
return 0;
}
If I try to do this, I get all sorts of errors... Next to that, my solution struct gets corrupted and the first position in list1 randomly changes back to 0.
I tried several things to mitigate this, but nothing seems to work. If I just pass on the solution to function1 by value, the programs seems to run, but more slowly, because it has to copy this large struct.
So my questions are:
1) Is it possible to pass (by reference) on a parameter that was passed by reference to another function, in function1?
2) What would be a better solution?
1) Is it possible to pass (by reference) on a parameter that was passed by reference to another function, in function1?
Yes, it is possible to pass the same variable, by reference to another function.
void f1(My_Class& m); // Forward declaration.
void f2(My_Class& m);
void f1(My_Class& m) // Definition.
{
f2(m);
}
void f2(My_Class& m)
{
;
}
The forward declaration gives the compiler a "heads up" on how functions are to be used (their syntax). Without forward declarations, the compiler would get the knowledge from their definitions. However, the definitions or forward declarations must come before the function call.
2) What would be a better solution?
Here are some ideas to improve your solution:
1) Use std::vector instead of arrays.
2) Consider a std::vector of structures, rather than an a structure of arrays:
struct List_Record
{
int item1;
int item2;
int item3;
int item4;
};
std::vector<List_Record> My_Lists(100);
// or
List_Record My_Array[100];
Having the items in a structure or record allows better data cache management by the processor (all items in a row are placed contiguously).
3) Create a method in the structure for initialization.
You should have a constructor that loads the data items with a default value.
Consider adding a method that loads the data items from a file (very useful for testing).

Multithreading with member functions and constructor carrying argument(s)

I have a situation in which i need to instantiate a vector of boost::threads to solve the following:
I have a class called Instrument to hold Symbol information, which looks something like below:
class Instrument
{
public:
Instrument(StringVector symbols, int i);
virtual ~Instrument();
const Instrument& operator= (const Instrument& inst)
{
return *this;
}
String GetSymbol() { return Symbol_; }
LongToSymbolInfoPairVector GetTS() { return TS_; }
bool OrganiseData(TimeToSymbolsInfoPairVector& input, int i);
static int getRandomNumber(const int low, const int high);
static double getProbability();
bool ConstructNewTimeSeries(const int low, const int high);
bool ReconstructTimeSeries(TimeToSymbolsInfoPairVector& reconstructeddata, int i);
private:
LongToSymbolInfoPairVector TS_;
String Symbol_;
const int checkWindow_;
String start_, end_;
long numberofsecsinaday_;
static std::default_random_engine generator_;
};
This class will have as many objects as the number of symbols. These symbols shall be accessed in another class Analysis for further work, whose constructor accepts the vector of the above Instrument class, as shown below.
class Analysis
{
public:
Analysis(std::vector<Instrument>::iterator start, std::vector<Instrument>::iterator end);
virtual ~Analysis();
bool buildNewTimeSeries(TimeToSymbolsInfoPairVector& reconstructeddata);
bool printData(TimeToSymbolsInfoPairVector& reconstructeddata);
private:
std::vector<Instrument> Instruments_;
};
Now i want to multithread this process so that i can separate out say 7 symbols per thread and spawn out, say, 4 threads.
Following is the updated main.
std::vector<Instrument>::iterator block_start = Instruments.begin();
int first = 0, last = 0;
for (unsigned long i=0; i<MAX_THREADS; i++)
{
std::vector<Instrument>::iterator block_end = block_start;
std::advance(block_end, block_size);
last = (i+1)*block_size;
Analysis* analyzed = new Analysis(block_start, block_end /*first, last*/);
analyzed->setData(output, first, last);
threads.push_back(std::thread(std::bind(&Analysis::buildNewTimeSeries, std::ref(*analyzed))));
block_start = block_end;
first = last;
}
for (int i=0; i<MAX_THREADS; i++)
{
(threads[i]).join();
}
This is evidently incorrect, although i know how to instantiate a thread's constructor to pass a class constructor an argument or a member function an argument, but i seem to be facing an issue when my purpose is:
a) Pass the constructor of class Analysis a subset of vector and
b) Call the buildNewTimeSeries(TimeToSymbolsInfoPairVector& reconstructeddata)
for each of the 4 threads and then later on join them.
Can anyone suggest a neat way of doing this please ?
The best way to go about partitioning a vector of resources (like std::vector in ur case) on to limited number of threads is by using a multi-threaded design paradigm called threadpools. There is no standard thread-pool in c++ and hence you might have to build one yourself(or use open source libraries). You can have a look at one of the many good opensource implementations here:- https://github.com/progschj/ThreadPool
Now, I am not going to be using threadpools, but will just give you a couple of suggestions to help u fix ur problem without modifying ur core functionality/idea.
In main you are dynamically creating vectors using new and are passing on the reference of the vector by dereferencing the pointer. Analysis* analyzed = new. I understand that your idea here, is to use the same vector analysis* in both main and the thread function. In my opinion this is not a good design. There is a better way to do it.
Instead of using std::thread use std::async. std::async creates tasks as opposed to threads. There are numerous advantages using tasks by using async. I do not want to make this a long answer by describing thread/tasks. But, one main advantage of tasks which directly helps you in your case is that it lets you return values(called future) from tasks back to the main function.
No to rewrite your main function async, tweak your code as follows,
Do not dynamically create a vector using new, instead just create a
local vector and just move the vector using std::move to the task
while calling async.
Modify Analysis::buildNewTimeSeries to accept rvalue reference.
Write a constructor for analysis with rvalue vector
The task will then modify this vector locally and then
return this vector to main function.
while calling async store the return value of the async
calls in a vector < future < objectType > >
After launching all the tasks using async, you can call the .get() on each of the element of this future vector.
This .get() method will return the vector modified and returned from
thread.
Merge these returned vectors into the final result vector.
By moving the vector from main to thread and then returning it back, you are allowing only one owner to have exclusive access on the vector. So you can not access a vector from main after it gets moved to thread. This is in contrast to your implementation, where both the main function and the thread function can access the newly created vector that gets passed by reference to the thread.

optimize output value using a class and public member

Suppose you have a function, and you call it a lot of times, every time the function return a big object. I've optimized the problem using a functor that return void, and store the returning value in a public member:
#include <vector>
const int N = 100;
std::vector<double> fun(const std::vector<double> & v, const int n)
{
std::vector<double> output = v;
output[n] *= output[n];
return output;
}
class F
{
public:
F() : output(N) {};
std::vector<double> output;
void operator()(const std::vector<double> & v, const int n)
{
output = v;
output[n] *= n;
}
};
int main()
{
std::vector<double> start(N,10.);
std::vector<double> end(N);
double a;
// first solution
for (unsigned long int i = 0; i != 10000000; ++i)
a = fun(start, 2)[3];
// second solution
F f;
for (unsigned long int i = 0; i != 10000000; ++i)
{
f(start, 2);
a = f.output[3];
}
}
Yes, I can use inline or optimize in an other way this problem, but here I want to stress on this problem: with the functor I declare and construct the output variable output only one time, using the function I do that every time it is called. The second solution is two time faster than the first with g++ -O1 or g++ -O2. What do you think about it, is it an ugly optimization?
Edit:
to clarify my aim. I have to evaluate the function >10M times, but I need the output only few random times. It's important that the input is not changed, in fact I declared it as a const reference. In this example the input is always the same, but in real world the input change and it is function of the previous output of the function.
More common scenario is to create object with reserved large enough size outside the function and pass large object to the function by pointer or by reference. You could reuse this object on several calls to your function. Thus you could reduce continual memory allocation.
In both cases you are allocating new vector many many times.
What you should do is to pass both input and output objects to your class/function:
void fun(const std::vector<double> & in, const int n, std::vector<double> & out)
{
out[n] *= in[n];
}
this way you separate your logic from the algorithm. You'll have to create a new std::vector once and pass it to the function as many time as you want. Notice that there's unnecessary no copy/allocation made.
p.s. it's been awhile since I did c++. It may not compile right away.
It's not an ugly optimization. It's actually a fairly decent one.
I would, however, hide output and make an operator[] member to access its members. Why? Because you just might be able to perform a lazy evaluation optimization by moving all the math to that function, thus only doing that math when the client requests that value. Until the user asks for it, why do it if you don't need to?
Edit:
Just checked the standard. Behavior of the assignment operator is based on insert(). Notes for that function state that an allocation occurs if new size exceeds current capacity. Of course this does not seem to explicitly disallow an implementation from reallocating even if otherwise...I'm pretty sure you'll find none that do and I'm sure the standard says something about it somewhere else. Thus you've improved speed by removing allocation calls.
You should still hide the internal vector. You'll have more chance to change implementation if you use encapsulation. You could also return a reference (maybe const) to the vector from the function and retain the original syntax.
I played with this a bit, and came up with the code below. I keep thinking there's a better way to do this, but it's escaping me for now.
The key differences:
I'm allergic to public member variables, so I made output private, and put getters around it.
Having the operator return void isn't necessary for the optimization, so I have it return the value as a const reference so we can preserve return value semantics.
I took a stab at generalizing the approach into a templated base class, so you can then define derived classes for a particular return type, and not re-define the plumbing. This assumes the object you want to create takes a one-arg constructor, and the function you want to call takes in one additional argument. I think you'd have to define other templates if this varies.
Enjoy...
#include <vector>
template<typename T, typename ConstructArg, typename FuncArg>
class ReturnT
{
public:
ReturnT(ConstructArg arg): output(arg){}
virtual ~ReturnT() {}
const T& operator()(const T& in, FuncArg arg)
{
output = in;
this->doOp(arg);
return this->getOutput();
}
const T& getOutput() const {return output;}
protected:
T& getOutput() {return output;}
private:
virtual void doOp(FuncArg arg) = 0;
T output;
};
class F : public ReturnT<std::vector<double>, std::size_t, const int>
{
public:
F(std::size_t size) : ReturnT<std::vector<double>, std::size_t, const int>(size) {}
private:
virtual void doOp(const int n)
{
this->getOutput()[n] *= n;
}
};
int main()
{
const int N = 100;
std::vector<double> start(N,10.);
double a;
// second solution
F f(N);
for (unsigned long int i = 0; i != 10000000; ++i)
{
a = f(start, 2)[3];
}
}
It seems quite strange(I mean the need for optimization at all) - I think that a decent compiler should perform return value optimization in such cases. Maybe all you need is to enable it.