Bashelapsed time: 400 msecelapsed time: 1405 msecelapsed time: 5797 msec
C++ (Qt)template <class R>struct getter : public boost::static_visitor<R>{ getter(size_t i) : index(i) {} template <class V> R operator()(V & v) const { return v[index]; } R operator()(R v) const { if (index) throw std::out_of_range("out of range"); return v; } private: size_t index;}; template <class R, class V>R& get(size_t i, V & v){ return boost::apply_visitor(getter<R&>(i), v);} const int TEST_COUNT = 50 * 1024 * 1024; struct CData { float val;}; struct CData2 { boost::variant<std::vector<float>, float> vec; // или boost::variant<std::vector<float>, std::array<float, MAGIC_BUF>> vec; // Или написать свою обёртку над таким вариантом, которая внешне была аналогична обычному вектору, например.}; struct CData3 { QList<float> vec;}; template <class F>void run(F f){ auto start = std::chrono::high_resolution_clock::now(); f(); auto stop = std::chrono::high_resolution_clock::now(); auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(stop-start).count(); std::cout << "elapsed time: " << elapsed << " msec" << std::endl;} int main(){ std::mt19937 gen; std::uniform_real_distribution<float> dist(0.0f, 1.0f); run([&]() { CData * data = new CData[TEST_COUNT]; for (int i = 0; i < TEST_COUNT; ++i) data[i].val = dist(gen); delete [] data; }); run([&] { CData2 * data2 = new CData2[TEST_COUNT]; for (int i = 0; i < TEST_COUNT; ++i) { data2[i].vec = dist(gen); } delete [] data2; }); run([&]{ CData3 * data3 = new CData3[TEST_COUNT]; for (int i = 0; i < TEST_COUNT; ++i) data3[i].vec.push_back(dist(gen)); delete [] data3; }); return 0;}
C++ (Qt)auto start = std::chrono::high_resolution_clock::now();f();auto stop = std::chrono::high_resolution_clock::now();auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(stop-start).count();std::cout << "elapsed time: " << elapsed << " msec" << std::endl;
C++ (Qt)QElapsedTimer t;t.start();f();std::cout << "elapsed time: " << t.elapsed() << " msec" << std::endl;
enum { // length of internal buffer, [1, 16] _BUF_SIZE = 16 / sizeof (value_type) < 1 ? 1 : 16 / sizeof (value_type)}; enum { // roundup mask for allocated buffers, [0, 15] _ALLOC_MASK = sizeof (value_type) <= 1 ? 15 : sizeof (value_type) <= 2 ? 7 : sizeof (value_type) <= 4 ? 3 : sizeof (value_type) <= 8 ? 1 : 0}; value_type *_Myptr() { // determine current pointer to buffer for mutable string return (this->_BUF_SIZE <= this->_Myres ? _STD addressof(*this->_Bx._Ptr) : this->_Bx._Buf); } const value_type *_Myptr() const { // determine current pointer to buffer for nonmutable string return (this->_BUF_SIZE <= this->_Myres ? _STD addressof(*this->_Bx._Ptr) : this->_Bx._Buf); } union _Bxty { // storage for small buffer or pointer to larger one value_type _Buf[_BUF_SIZE]; pointer _Ptr; char _Alias[_BUF_SIZE]; // to permit aliasing } _Bx; size_type _Mysize; // current length of string size_type _Myres; // current storage reserved for string
C++ (Qt)struct CData2 { boost::variant<std::vector<float>, float> vec; // или boost::variant<std::vector<float>, std::array<float, MAGIC_BUF>> vec; // Или написать свою обёртку над таким вариантом, которая внешне была аналогична обычному вектору, например.};
C++ (Qt)int count;float * data; // и просто new[] и delete[]
Bashelapsed time: 393 msecelapsed time: 800 msec std::valarrayelapsed time: 5659 msec QList