首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >加速boost::iostreams::filtering_streambuf

加速boost::iostreams::filtering_streambuf
EN

Stack Overflow用户
提问于 2022-07-02 02:29:33
回答 1查看 73关注 0票数 1

我是C++流概念的新手,我想征求一些一般性的建议,以加快我在图像处理中的代码。我使用流缓冲区boost::iostreams::filtering_streambuf从文件加载和解压缩图像,如这个职位另一个职位中所建议的那样。演出不令人满意。

相关代码如下:

代码语言:javascript
复制
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。我觉得太久了。因此,我向社会人士寻求一些改善的意见。

谢谢你花时间在我的岗位上!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-02 10:01:53

您可以使用块IO。

代码语言:javascript
复制
char buf[4096];
inflated.read(buf, sizeof(buf));
std::for_each(buf, buf + inflated.gcount(), _fill_);

然而,我也认为在_fill_中可能会浪费大量的时间,在那里,一些维度正在被重塑。太武断了。

请注意,有几个库具有透明地重新索引多维数据的特性,因此您可能会节省时间,只需线性复制源数据并访问:

  • Boost MultiArray (允许您指定存储顺序、方向和偏移量:存储
  • Boost GIL允许您直接使用来自交错/平面缓冲区的图像数据:image.html
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72836070

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档