I am trying to write int61_t data to a ply file (a text file with a special header). I a piece of code that does this with a time consuming loop I am trying to speed it up. I want to avoid the time spent iterating through the array by putting my data directly into ofs.write. Can I do this?
This is what I've tried
The functional, but slow, code is as follows:
int width = point_cloud_image.get_width_pixels();
int height = point_cloud_image.get_height_pixels();
int i_max = width * height;
// get data
int16_t* point_cloud_image_data = (int16_t*)(void*)point_cloud_image.get_buffer();
std::stringstream ss;
for (int i = 0; i < i_max; i++) // executes 921600 times - this is the bottleneck
{
ss << point_cloud_image_data[3 * i + 0\] << " " << point_cloud_image_data[3 * i + 1\] << " " << point_cloud_image_data[3 * i + 2] << "\n";
}
// save to the ply file
std::ofstream ofs("myfile.ply", std::ios::out | std::fstream::binary); // text mode first
ofs << "ply\n" << "format ascii 1.0\n" << "element vertex" << " " << i_max << "\n" << "property float x\n" << "property float y\n" << "property float z\n" << "end_header\n" << std::endl;
ofs.write(ss.str().c_str(), (std::streamsize)ss.str().length());
ofs.close();
I want to avoid the time spent iterating through the array by putting my point_cloud_image_data pointer directly into ofs.write. My code to do that looks like this:
int width = point_cloud_image.get_width_pixels();
int height = point_cloud_image.get_height_pixels();
int i_max = width * height;
// get data
int16_t* point_cloud_image_data = (int16_t*)(void*)point_cloud_image.get_buffer();
// save to the ply file
std::ofstream ofs("myfile.ply", std::ios::out | std::fstream::binary); // text mode first
ofs << "ply\n" << "format ascii 1.0\n" << "element vertex" << " " << i_max << "\n" << "property float x\n" << "property float y\n" << "property float z\n" << "end_header\n" << std::endl;
ofs.write((char*)(char16_t*)point_cloud_image_data, i_max);
ofs.close();
This is a lot faster, but now point_cloud_image_data is written in binary (the file contains characters like this: ¥ûú). How can I write the array to the text file without a time consuming loop?
Integers are stored in the computer in binary representation. To write an array of integer values to a text file, each one needs to be converted to a series of decimal digits. So you're going to need a loop. Even with buffering and compiler optimizations enabled, conversion of binary to text and back will inevitably be slower than directly working with binary data.
But if all you care about is raw performance, the PLY format can actually be binary. So your second attempt might actually work and produce a working (albeit non-human-readable) PLY file.
The
is_little_endian
check is optional and can be omitted, but it makes the code a little bit more portable.