我是C++流概念的新手,我想征求一些一般性的建议,以加快我在图像处理中的代码。我使用流缓冲区boost::iostreams::filtering_streambuf从文件加载和解压缩图像,如这个职位和另一个职位中所建议的那样。演出不令人满意。
相关代码如下:
template <int _NCH>
class MultiChImg {
public:
...
...
private:
std::atomic<bool> __in_operation;
std::atomic<bool> __content_loaded;
char **_IMG[_NCH];
int _W, _H;
void dcmprss ( const std::string & file_name, bool is_decomp = true) {
...
...
// decompress
int counter = 0, iw = -1, ih = -1, _r = 0;
auto _fill_ = [&](const char c){
_r = counter % _NCH ; // was 3 for RGB mindset
if ( _r == 0 ) {
iw++; // fast index
if ( iw%_W==0 ) { iw=0; ih++; } // slow index
}
_IMG[_r][_H-1-ih][iw] = c;
counter ++ ;
} ;
auto EoS = std::istreambuf_iterator<char>() ;
// char buf[4096]; // UPDATE: improved code according to @sehe
if ( is_decomp ) {
// decompress
bio::filtering_streambuf<bio::input> input;
input.push( bio::gzip_decompressor() ); //
input.push( fstrm );
std::basic_istream<char> inflated( &input );
auto T3 = timing(T2, "Timing : dcmprss() prepare decomp ") ;
// assign values to _IMG (0=>R, 1=>G, 2=>B)
// TODO // bottleneck
std::for_each(
std::istreambuf_iterator<char>(inflated), EoS, _fill_ );
// UPDATE: improved code according to @sehe , replace the previous two lines
// while (inflated.read(buf, sizeof(buf)))
// std::for_each(buf, buf + inflated.gcount(), _fill_);
auto T4 = timing(T3, "Timing : dcmprss() decomp+assign ") ;
} else {
// assign values to _IMG (0=>R, 1=>G, 2=>B)
// TODO // bottleneck
std::for_each(
std::istreambuf_iterator<char>(fstrm), EoS, _fill_ ); // different !
// UPDATE: improved code according to @sehe , replace the previous two lines
// while (fstrm.read(buf, sizeof(buf)))
// std::for_each(buf, buf + fstrm.gcount(), _fill_);
auto T3 = timing(T2, "Timing : dcmprss() assign ") ;
}
assert(counter == _NCH*_H*_W);
...
...
};
...
...
}瓶颈似乎是for_each()部分,在这里我迭代流,要么通过std::istreambuf_iterator<char>(inflated)迭代inflated,要么通过std::istreambuf_iterator<char>(fstrm)迭代fstrm来应用lambda函数_fill_。这个lambda函数将流中的字节传输到多维数组类成员_IMG中的指定位置。
更新:由于内存泄漏,计时不正确。我已经更正过了。
上述函数dcmprss()的定时结果为:30 of大小的.gz文件为450 of,未压缩文件为400 of。我觉得太久了。因此,我向社会人士寻求一些改善的意见。
谢谢你花时间在我的岗位上!
发布于 2022-07-02 10:01:53
您可以使用块IO。
char buf[4096];
inflated.read(buf, sizeof(buf));
std::for_each(buf, buf + inflated.gcount(), _fill_);然而,我也认为在_fill_中可能会浪费大量的时间,在那里,一些维度正在被重塑。太武断了。
请注意,有几个库具有透明地重新索引多维数据的特性,因此您可能会节省时间,只需线性复制源数据并访问:
https://stackoverflow.com/questions/72836070
复制相似问题