patterncppMinor
Fill a vector with uniformly distributed random complex numbers
Viewed 0 times
randomuniformlywithnumbersdistributedvectorfillcomplex
Problem
I want to fill an array of complex numbers using a uniform generator. I thought up the next code. (
So I though up using static variables within the lambda expression. Is that inefficient? Alternatively I would create them outside of the lambda, and put them on the capture list. But I don't need them outside of the lambda, so this seems cleaner to me.
Complex is a simple fixed-point complex data type.)std::generate(inputData.begin(), inputData.end(), []()-> Complex {
static std::default_random_engine generator;
static std::normal_distribution distribution(0.0, 0.5); // mean = 0.0, stddev = 0.5
return Complex(distribution(generator), distribution(generator));
});So I though up using static variables within the lambda expression. Is that inefficient? Alternatively I would create them outside of the lambda, and put them on the capture list. But I don't need them outside of the lambda, so this seems cleaner to me.
Solution
The problem with this is that it leaks memory, although not in the traditional sense of leaking.
Function
On the other hand, the amount of memory it eats up is pretty small and constant, so for almost all purposes, it shouldn't make too big of a difference. Even if you repeatedly called a function that had this code in it, the static variable would live and not be recreated. Just don't use this in a way that generates the lambda 100s of times, such as in intense template metaprogramming.
In C++17, if you were using this to initialize a big enough vector, you could make use of execution policies to parallelize this like so:
This has the added benefit that these variables will be destructed when the threads used finish, although when that happens is mostly unclear.
Function
static variables live till the end of the program. So while generator and distribution are only created when this code is first run, they only get destroyed at the end of your program even though you never use them later. This eats up memory the entire time.On the other hand, the amount of memory it eats up is pretty small and constant, so for almost all purposes, it shouldn't make too big of a difference. Even if you repeatedly called a function that had this code in it, the static variable would live and not be recreated. Just don't use this in a way that generates the lambda 100s of times, such as in intense template metaprogramming.
In C++17, if you were using this to initialize a big enough vector, you could make use of execution policies to parallelize this like so:
std::generate(std::execution::par_unseq, inputData.begin(), inputData.end(), []()-> Complex {
thread_local std::default_random_engine generator; // thread_local so we don't have to do any locking
thread_local std::normal_distribution distribution(0.0, 0.5); // mean = 0.0, stddev = 0.5
return Complex(distribution(generator), distribution(generator));
});This has the added benefit that these variables will be destructed when the threads used finish, although when that happens is mostly unclear.
Code Snippets
std::generate(std::execution::par_unseq, inputData.begin(), inputData.end(), []()-> Complex {
thread_local std::default_random_engine generator; // thread_local so we don't have to do any locking
thread_local std::normal_distribution<double> distribution(0.0, 0.5); // mean = 0.0, stddev = 0.5
return Complex(distribution(generator), distribution(generator));
});Context
StackExchange Code Review Q#155513, answer score: 3
Revisions (0)
No revisions yet.