使用bigendian格式从QByteArray获取float数组的有效方法

时间:2017-01-13 10:09:16

标签: c++ c qt

我有一个带BigEndian格式的QbyteArray变量 我希望用最小的进程从该变量中获取一个float数组。 什么是最快的方式?

现在我使用以下代码,但效率不高,我认为应该有更好的方法吗?

请帮助

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);
}

2 个答案:

答案 0 :(得分:1)

快速回答,移除对QByteArray::mid()的调用,仅使用const函数来防止额外的写时复制。除此之外我不认为你可以更有效率,也许可以内联这个功能。

inline float getValue(const QByteArray &dataBytes, int i){  
    const qint32 level = qFromBigEndian<qint32>(&static_cast<const qint32 *>(dataBytes.constData())[i]);
    return level*1.0;
}

答案 1 :(得分:1)

为什么不制作迭代器并构建std::vector?不损失效率加上完全安全:

#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;
}

关于godbolt的证据:https://godbolt.org/g/PG3H2V