C++ — fastest way to set an array of floats to the same value


C++ — fastest way to set an array of floats to the same value



I naively thought I could use memset for this, but apparently memset is only for chars. Is there a memset-type thing that will work on an array of floats? Or is simple iteration the fastest way to copy a single value to every spot in an array?





If you're setting the floats to zero then memset does work (assuming the standard IEEE 754 float representation). You have to get the casts and array size calculation right though.
– bames53
Nov 18 '11 at 19:55




7 Answers
7



I won't speak to what code runs the fastest. You should compare them yourself, in the intended environment.



But, here are two readable, maintainable, correct solutions.


std::fill(std::begin(array), std::end(array), 3.14);



Or, if you have a dynamic array:


std::fill(array, array+size, 3.14);





+1, I need to become more familiar with the standard library's algorithms.
– Seth Carnegie
Nov 18 '11 at 19:48





Or, std::fill_n(array, size, 3.14);
– Nawaz
Nov 18 '11 at 19:49


std::fill_n(array, size, 3.14);





@Nawaz Interesting :)
– AraK
Nov 18 '11 at 19:51



The standard way is:


std::fill(float_array, float_array + array_size, 0.0f);



I suspect you could beat this standard facility without non-standard methods.



I would recommend std::fill.


std::fill


std::fill(
floatArray + 0, floatArray + LENGTH
, newValue
);



The compiler knows what you are trying to do here, and decent implementations can provide appropiate optimizations.





If your compiler supports the current version of C++ (C++11) you can use the std::begin() and std::end() functions instead of trying to manually calculate the end of the array. fill(begin(floatArray),end(floatArray),newValue)
– bames53
Nov 18 '11 at 19:51


fill(begin(floatArray),end(floatArray),newValue)





@bames53: Thats assuming its a static array.
– K-ballo
Nov 18 '11 at 19:53






well if it's a dynamic array then it's a std::vector, right? ;)
– bames53
Nov 18 '11 at 20:00



You just have to loop through and set all the values to 0 (which is what memset does anyway):


memset


// this is a generic function to set all the elements of an array of any type (that has a public assignment operator and copy constructor) to a specific value
template<typename T>
void setarray(T* array, const T val, unsigned int array_size) {
for (unsigned int i = 0; i < array_size; ++i)
array[i] = val;
}

float* floatArray = new float[x];

setarray(floatArray, 0, x);



If the particular value you want to set all the elements of the array to happens to be 0 and you are using a compile time array, you can use an initialiser list:


float myArray[CONSTANT] = {}; // all values are 0





@Rob whoops, bad reading on my part. Fixed.
– Seth Carnegie
Nov 18 '11 at 19:47





You don't need to write your own function for this. std::fill works just fine.
– bames53
Nov 18 '11 at 19:49





@bames53 hence my comment on Rob's answer
– Seth Carnegie
Nov 18 '11 at 19:50





Ah, that wasn't there when I read his post. Rob's answer has gone from 0 to 10 votes pretty quickly!
– bames53
Nov 18 '11 at 19:58



There is memfill function
http://manpages.ubuntu.com/manpages/natty/man3/memfill.3pub.html


memfill



in publib nonstandard library. It can be used in ubuntu.


#include <publib.h>

float a=4.4;
memfill(buf_ptr, buf_size, &a, sizeof(float) );



You can use threads and initialize sub-ranges with separate threads.





since memory write speed is the bottleneck, would that help at all? I have a feeling it will be slower (even without the overhead of creating the threads)
– Karoly Horvath
Nov 18 '11 at 19:48




If you have a multiple dimensional float array then you could do something like this:


float myMultiDimensionFloats[5][250];
float myfloats[250];

for(int i=0; i<250;i++)
myfloats[i] = 3.14f; // the value you want to store in each float entry

for(int ii=0; ii<5; ii++)
CopyMemory(myMultiDimensionFloats[ii], &myfloats, sizeof(myMultiDimensionFloats[ii]));



Or if you want to use the template from "Seth Carnegie" :


#define LEN(arr) ((int) (sizeof (arr) / sizeof (arr)[0]))
float myMultiDimensionFloats[5][250];
setarray(myMultiDimensionFloats[0], 3.14f, LEN(myMultiDimensionFloats) * LEN(myMultiDimensionFloats[0]));






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Comments

Popular posts from this blog

paramiko-expect timeout is happening after executing the command

Opening a url is failing in Swift

Export result set on Dbeaver to CSV