Я попробовал ваш код и сделал несколько небольших оптимизаций хипшота, но получил непротиворечивые результаты. Базовая линия была для меня ~ 14 с, и она все время оставалась близкой к этому. Хорошая работа -O3
.
Я заменил ваш std::vector<std::vector<double>>
одномерной версией и std::copy
записал его на диск с незначительным улучшением.
Только когда я сдался ивыгрузил память как есть (, а не как .csv
) на диск, у меня было до 1-3 секунд.
Большой недостаток в том, что то, что я сбросил, не переносимов любом случае. Можно надеяться, что в удачный день его можно будет снова прочитать на том же компьютере, но я бы не рекомендовал выводить double
s таким образом:
#include <chrono>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
typedef std::chrono::high_resolution_clock Clock;
// custom 2D array with a 1D memory layout
template<typename T>
class array2d {
public:
array2d(size_t h, size_t w, const T& value = T{}) : data_(h * w, value), w_(w) {}
inline double* operator[](size_t y) { return &data_[y * w_]; }
inline double const* operator[](size_t y) const { return &data_[y * w_]; }
inline size_t width() const { return w_; }
T const* data() const { return data_.data(); }
size_t size() const { return data_.size(); }
private:
std::vector<T> data_;
size_t w_;
};
using VecVecD = array2d<double>;
void test_file_write_stream() {
VecVecD v(10000, 2000, 1.23456789);
const std::string delimiter(",");
const std::string file_path("c:\\junk\\speedtest.csv");
auto t1_stream = Clock::now();
std::ofstream ostream(file_path.c_str(), std::ios::binary);
if(!ostream) return;
ostream << std::setprecision(12);
/* this may give a somewhat better performance than yours, but not much:
std::copy(v.data(), v.data() + v.size(),
std::ostream_iterator<double>(ostream, delimiter));
*/
// non-portable binary dump
ostream.write(reinterpret_cast<const char*>(v.data()),
static_cast<std::streamsize>(v.size() * sizeof(double)));
auto t2_stream = Clock::now();
auto elapsed_s =
std::chrono::duration_cast<std::chrono::seconds>(t2_stream - t1_stream);
std::cout << "Stream test: " << elapsed_s.count() << " seconds" << std::endl;
}
int main(int, char**) {
test_file_write_stream();
}