Weird profiling with zlib

I play with zliband have (simplified) code as follows:

#include <cstring>  // memset
#include <string>

#include <zlib.h>

#include <cstdio>

const int compressionLevel_ = 9;
const size_t BUFFER_SIZE = 1024 * 8;
char buffer_[BUFFER_SIZE];

std::string compress(const char *data, size_t const size){
    z_stream zs;
    memset(&zs, 0, sizeof(zs));

    if (deflateInit(&zs, compressionLevel_) != Z_OK)
        return {};

    zs.next_in  = reinterpret_cast<Bytef *>( const_cast<char *>( data ) );
    zs.avail_in = static_cast<uInt>( size );

    std::string out;

    int result;
    do {
        zs.next_out  = reinterpret_cast<Bytef *>(buffer_);
        zs.avail_out = BUFFER_SIZE;

        result = deflate(&zs, Z_FINISH);

        if (out.size() < zs.total_out){
            // COMMENT / UNCOMMENT HERE !!!
            out.append(buffer_, zs.total_out - out.size() );
        }
    } while (result == Z_OK);

    deflateEnd(&zs);

    if (result != Z_STREAM_END)
        return {};

    return out;
}


int main(){
    const char *original = "Hello World";
    size_t const original_size = strlen(original);

    for(size_t i = 0; i < 1000000; ++i){
        const auto cdata = compress(original, original_size);
    }
}

The real code is bigger because it decompresses and checks if the unpacked line was compared to the original line.

If I compile with clang or gcc, everything takes about 5 seconds.

However ... If I comment on this line:

        if (out.size() < zs.total_out){
            // COMMENT / UNCOMMENT HERE !!!
        //  out.append(buffer_, zs.total_out - out.size() );
        }

Execution takes 30 seconds !!!

If I try on a fast Linux server, the time will be accordingly 3 seconds versus 18 seconds.

I tried the same on macOS with clang and there wasn’t much timing difference.

I tried with different levels of optimization, and the result was saved - if you comment, you will get ~ 10 times longer execution time.

What could be the reason?

Update

I tried Cygwin with gcc - no time difference there.

Linux Arm CPU gcc - 25 2:20 .

+4
1

time, , uncommented - :

$ time ./main 

real    0m5.309s
user    0m5.304s
sys     0m0.004s

, 5 , , . :

$ time ./main 

real    0m29.061s
user    0m7.424s
sys     0m21.660s

, , , 5000 , , , , - - .

oprofile , :

samples  %        image name               symbol name
62451    45.2376  libz.so.1.2.8            /lib64/libz.so.1.2.8
61905    44.8421  libc-2.19.so             memset
2752      1.9935  libc-2.19.so             _int_free
2549      1.8464  libc-2.19.so             _int_malloc
2474      1.7921  libc-2.19.so             malloc_consolidate
2263      1.6392  no-vmlinux               /no-vmlinux
1365      0.9888  libc-2.19.so             malloc
723       0.5237  libc-2.19.so             __memcpy_sse2_unaligned
711       0.5150  libstdc++.so.6.0.21      /usr/lib64/libstdc++.so.6.0.21
478       0.3462  libc-2.19.so             free
366       0.2651  main                     main
6         0.0043  ld-2.19.so               _dl_lookup_symbol_x
2         0.0014  ld-2.19.so               _dl_relocate_object
2         0.0014  ld-2.19.so               do_lookup_x
1        7.2e-04  ld-2.19.so               _dl_name_match_p
1        7.2e-04  ld-2.19.so               check_match.9478
1        7.2e-04  ld-2.19.so               strcmp
1        7.2e-04  libc-2.19.so             _dl_addr

:

samples  %        image name               symbol name
594605   74.6032  no-vmlinux               /no-vmlinux
102981   12.9207  libc-2.19.so             memset
72822     9.1368  libz.so.1.2.8            /lib64/libz.so.1.2.8
9093      1.1409  libc-2.19.so             _int_malloc
3987      0.5002  libc-2.19.so             sysmalloc
3365      0.4222  libc-2.19.so             _int_free
2119      0.2659  libc-2.19.so             brk
1958      0.2457  libc-2.19.so             systrim.isra.1
1597      0.2004  libc-2.19.so             free
1217      0.1527  libc-2.19.so             malloc
1123      0.1409  libc-2.19.so             sbrk
786       0.0986  libc-2.19.so             __memcpy_sse2_unaligned
688       0.0863  libc-2.19.so             __default_morecore
669       0.0839  main                     main
5        6.3e-04  ld-2.19.so               _dl_relocate_object
4        5.0e-04  ld-2.19.so               do_lookup_x
2        2.5e-04  ld-2.19.so               strcmp
1        1.3e-04  ld-2.19.so               _dl_lookup_symbol_x
1        1.3e-04  libc-2.19.so             _dl_addr

strace , 64 ( , ), 4000063 , :

brk(0x6c0000)                           = 0x6c0000
brk(0x6e2000)                           = 0x6e2000
brk(0x6d2000)                           = 0x6d2000
brk(0x6c2000)                           = 0x6c2000
brk(0x6c0000)                           = 0x6c0000
brk(0x6e2000)                           = 0x6e2000
brk(0x6d2000)                           = 0x6d2000
brk(0x6c2000)                           = 0x6c2000
brk(0x6c0000)                           = 0x6c0000

, -. , , / , , , , , std::string out = "1";, "" , .

, - glibc, ( , , brk()), . ( ) , glibc . glibc - (. man mallopt), "" () :

$ time MALLOC_TRIM_THRESHOLD_=-1 ./main 

real    0m5.094s
user    0m5.096s
sys     0m0.000s

, . , C ( glibc), .

+6

Source: https://habr.com/ru/post/1654585/


All Articles