Reputation: 368
I have a QbyteArray variable with BigEndian Format I want to get a float array from that variable with the minimum process. what is the Fastest way to do?
Now I am using following code but its not efficient and I think there should be a better way?
please help
float getValue(QByteArray dataBytes, int i){
QByteArray data = dataBytes.mid(i*4, 4);
qint32 level = qFromBigEndian<qint32>((uchar*)data.data());
float result = level*1.0;
}
float *f = new float[20];
for (int i=0;i<20;i++){
f[i] = getValue(myDataBytes, i);
}
Upvotes: 0
Views: 1056
Reputation: 69882
Why not make an iterator and build a std::vector
? No loss of efficiency plus complete safety:
#include <cstdint>
#include <algorithm>
#include <vector>
#include <iterator>
// simulate types
using qint32 = std::int32_t;
struct QByteArray {
QByteArray mid(int, int);
const std::uint8_t* data() const;
const std::size_t* size() const;
};
// simulate functions
template<class T> T qFromBigEndian(const std::uint8_t*);
// iterator to convert big endian byte streams to ints
struct big_endian_ints_iterator
: std::iterator<std::forward_iterator_tag, std::int32_t>
{
big_endian_ints_iterator(const std::uint8_t * p) : ptr_(p) {}
big_endian_ints_iterator& operator+=(std::size_t i) {
ptr_ += 4 * i;
return *this;
}
big_endian_ints_iterator& operator++() {
ptr_ += 4;
return *this;
}
big_endian_ints_iterator operator++(int) {
auto tmp = *this;
ptr_ += 4;
return tmp;
}
value_type operator*() const {
return qFromBigEndian<std::int32_t>(ptr_);
}
bool operator!=(const big_endian_ints_iterator& r) const {
return r.ptr_ != ptr_;
}
bool operator==(const big_endian_ints_iterator& r) const {
return r.ptr_ == ptr_;
}
const std::uint8_t* ptr_;
};
big_endian_ints_iterator operator+(big_endian_ints_iterator l, std::size_t r)
{
return l += r;
}
std::vector<float> test(QByteArray const& myDataBytes)
{
auto first = big_endian_ints_iterator(myDataBytes.data());
std::vector<float> f(first, first + 20);
return f;
}
proof on godbolt: https://godbolt.org/g/PG3H2V
Upvotes: 1
Reputation: 8311
Quick answer, remove the call to QByteArray::mid()
and use only const
functions to prevent extra copy-on-write. Other than that I don't think you can be more efficient, maybe inline the function.
inline float getValue(const QByteArray &dataBytes, int i){
const qint32 level = qFromBigEndian<qint32>(&static_cast<const qint32 *>(dataBytes.constData())[i]);
return level*1.0;
}
Upvotes: 1