简体   繁体   English

加速 boost::iostreams::filtering_streambuf

[英]Speeding up boost::iostreams::filtering_streambuf

I am new to the C++ concept of streams and want to ask for some general advice to speed up my code in image processing .我是 C++ 流概念的新手,想寻求一些一般性建议,以加快我在图像处理中的代码。 I use a stream buffer boost::iostreams::filtering_streambuf to load and decompress the image from a file, as suggested in this post and another post .我使用流缓冲区boost::iostreams::filtering_streambuf从文件中加载和解压缩图像,如本文另一篇文章中所建议的那样。 The performance is not satisfactory.表现并不令人满意。

The relavent code is the following:相关代码如下:


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);

            ...
            ...
        };
...
...
}

The bottleneck appears to be the for_each() part, where I iterate the stream, either inflated via std::istreambuf_iterator<char>(inflated) , or fstrm via std::istreambuf_iterator<char>(fstrm) , to apply a lambda function _fill_ .瓶颈似乎是for_each()部分,我在其中迭代流,通过std::istreambuf_iterator<char>(inflated) inflated通过 std:: fstrm std::istreambuf_iterator<char>(fstrm)的 fstrm 来应用 lambda 函数_fill_ This lambda function transfers the bytes in the stream to the designated place in the multi-dimensional array class member _IMG .此 lambda 函数将流中的字节传输到多维数组类成员_IMG中的指定位置。

UPDATE: the timing was incorrect due to memory leakage.更新:由于内存泄漏,时间不正确。 I've corrected that.我已经纠正了。

The timing results of the above function dcmprss() are 450ms for a .gz file of 30MB size, 400ms for uncompressed file.上述函数dcmprss()的计时结果对于 30MB 大小的 .gz 文件为 450ms,对于未压缩文件为 400ms。 I think it takes too long.我认为这需要太长时间。 So I am asking the community for some kind advice to improve.所以我要求社区提供一些改进的建议。

Thanks for your time on my post!感谢您花时间在我的帖子上!

You can use blockwise IO您可以使用分块 IO

char buf[4096];
inflated.read(buf, sizeof(buf));
std::for_each(buf, buf + inflated.gcount(), _fill_);

However, I also think considerable time might be wasted in _fill_ where some dimensions are reshaped.但是,我也认为可能会在_fill_中浪费相当多的时间,因为某些维度会被重新塑造。 That feels arbitrary.感觉很随意。

Note that several libraries have the features to transparently re-index multi-dimensional data, so you may potentially save time just linearly copy the source data and accessing that:请注意,有几个库具有透明地重新索引多维数据的功能,因此您可能会节省时间,只需线性复制源数据并访问它:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用boost :: iostreams :: filtering_streambuf解压缩zlib数据 - Uncompressing zlib data using boost::iostreams::filtering_streambuf trouble boost property_tree :: json_parser :: read_json&iostreams :: filtering_streambuf - boost property_tree::json_parser::read_json & iostreams::filtering_streambuf c++ boostfiltering_streambuf只读取一些数据 - c++ boost filtering_streambuf read only some data 将文件从Boost filtering_streambuf解压缩到std :: vector <char> ? - Decompress file from Boost filtering_streambuf to std::vector<char>? 将文件从Boost filter_streambuf解压缩到std :: vector <unsigned char> ? - Decompress file from Boost filtering_streambuf to std::vector<unsigned char>? 将 boost::filtering_streambuf 与 newline_filter 一起使用时为空文件 - Empty file when using boost::filtering_streambuf with newline_filter binary_oarchive 和 filtering_streambuf 的析构函数非常慢 - Very slow destructors of binary_oarchive and filtering_streambuf 增强过滤streambuf无法初始化流 - boost filtering streambuf unable to initialise stream Boost.Iostream与iostream / streambuf重载用于位流I / O - Boost.Iostreams vs. iostream/streambuf overloading for bitstream I/O boost :: iostreams :: filtering_stream的基础流的类型是什么? - What is the type of the underlying stream of a boost::iostreams::filtering_stream?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM