LINUX.ORG.RU

История изменений

Исправление MOPKOBKA, (текущая версия) :

Свои рейнджи мне делать не хочется, поэтому для наглядности сделал такой тест, где видно что compose на С++ может вообще не влиять, или даже влиять положительно.

Тут вызов compose на каждую итерацию, ты можешь увеличить его вложенность.

#include <iostream>

template <typename F1, typename F2> struct compose {
    F1 f1; F2 f2;
    compose(F1 f1, F2 f2) : f1{f1}, f2{f2} {}
    auto operator ()(auto x) { return f1(f2(x)); }
};

void test_pure(int argc, char **argv) {
    long r = 0;
    long end = atoi(argv[1]) + 1;
    for (long i = 1; i < end; ++i) {
        if ((i % 2) == 0) r += i;
    }
    std::cout << r << "\n";
}

void test_lambda(int argc, char **argv) {
    long r = 0;
    auto f = [](long x) { return x == 0; };
    auto g = [](long x){return x % 2;};
    long end = atoi(argv[1]) + 1;
    for (long i = 1; i < end; ++i) {
        if ((i % 2) == 0) r += i;
    }
    std::cout << r << "\n";
}

void test_compose(int argc, char **argv) {
    long r = 0;
    auto cond = compose([](long x) { return x == 0; }, [](long x){return x % 2;});
    long end = atoi(argv[1]) + 1;
    for (long i = 1; i < end; ++i) {
        if (cond(i)) r += i;
    }
    std::cout << r << "\n";
}

int main(int argc, char **argv) {
    switch(argv[2][0]) {
        case 'p':
            test_pure(argc, argv);
            break;
        case 'l':
            test_lambda(argc, argv);
            break;
        case 'c':
            test_compose(argc, argv);
            break;
    }
}
% g++-14 -std=c++23 -Ofast main.cpp; time ./a.out 2000000000 p
1000000001000000000

real	0m0,519s
user	0m0,518s
sys	0m0,001s

% g++-14 -std=c++23 -Ofast main.cpp; time ./a.out 2000000000 l
1000000001000000000

real	0m0,520s
user	0m0,519s
sys	0m0,001s

% g++-14 -std=c++23 -Ofast main.cpp; time ./a.out 2000000000 c
1000000001000000000

real	0m0,458s
user	0m0,457s
sys	0m0,001s

Исправление MOPKOBKA, :

Свои рейнджи мне делать не хочется, поэтому для наглядности сделал такой тест, где видно что compose на С++ может вообще не влиять, или даже влиять положительно.

#include <iostream>

template <typename F1, typename F2> struct compose {
    F1 f1; F2 f2;
    compose(F1 f1, F2 f2) : f1{f1}, f2{f2} {}
    auto operator ()(auto x) { return f1(f2(x)); }
};

void test_pure(int argc, char **argv) {
    long r = 0;
    long end = atoi(argv[1]) + 1;
    for (long i = 1; i < end; ++i) {
        if ((i % 2) == 0) r += i;
    }
    std::cout << r << "\n";
}

void test_lambda(int argc, char **argv) {
    long r = 0;
    auto f = [](long x) { return x == 0; };
    auto g = [](long x){return x % 2;};
    long end = atoi(argv[1]) + 1;
    for (long i = 1; i < end; ++i) {
        if ((i % 2) == 0) r += i;
    }
    std::cout << r << "\n";
}

void test_compose(int argc, char **argv) {
    long r = 0;
    auto cond = compose([](long x) { return x == 0; }, [](long x){return x % 2;});
    long end = atoi(argv[1]) + 1;
    for (long i = 1; i < end; ++i) {
        if (cond(i)) r += i;
    }
    std::cout << r << "\n";
}

int main(int argc, char **argv) {
    switch(argv[2][0]) {
        case 'p':
            test_pure(argc, argv);
            break;
        case 'l':
            test_lambda(argc, argv);
            break;
        case 'c':
            test_compose(argc, argv);
            break;
    }
}
% g++-14 -std=c++23 -Ofast main.cpp; time ./a.out 2000000000 p
1000000001000000000

real	0m0,519s
user	0m0,518s
sys	0m0,001s

% g++-14 -std=c++23 -Ofast main.cpp; time ./a.out 2000000000 l
1000000001000000000

real	0m0,520s
user	0m0,519s
sys	0m0,001s

% g++-14 -std=c++23 -Ofast main.cpp; time ./a.out 2000000000 c
1000000001000000000

real	0m0,458s
user	0m0,457s
sys	0m0,001s

Исходная версия MOPKOBKA, :

Свои рейнджи мне делать не хочется, поэтому для наглядности сделал такой тест:

#include <iostream>

template <typename F1, typename F2> struct compose {
    F1 f1; F2 f2;
    compose(F1 f1, F2 f2) : f1{f1}, f2{f2} {}
    auto operator ()(auto x) { return f1(f2(x)); }
};

void test_pure(int argc, char **argv) {
    long r = 0;
    long end = atoi(argv[1]) + 1;
    for (long i = 1; i < end; ++i) {
        if ((i % 2) == 0) r += i;
    }
    std::cout << r << "\n";
}

void test_lambda(int argc, char **argv) {
    long r = 0;
    auto f = [](long x) { return x == 0; };
    auto g = [](long x){return x % 2;};
    long end = atoi(argv[1]) + 1;
    for (long i = 1; i < end; ++i) {
        if ((i % 2) == 0) r += i;
    }
    std::cout << r << "\n";
}

void test_compose(int argc, char **argv) {
    long r = 0;
    auto cond = compose([](long x) { return x == 0; }, [](long x){return x % 2;});
    long end = atoi(argv[1]) + 1;
    for (long i = 1; i < end; ++i) {
        if (cond(i)) r += i;
    }
    std::cout << r << "\n";
}

int main(int argc, char **argv) {
    switch(argv[2][0]) {
        case 'p':
            test_pure(argc, argv);
            break;
        case 'l':
            test_lambda(argc, argv);
            break;
        case 'c':
            test_compose(argc, argv);
            break;
    }
}
% g++-14 -std=c++23 -Ofast main.cpp; time ./a.out 2000000000 p
1000000001000000000

real	0m0,519s
user	0m0,518s
sys	0m0,001s

% g++-14 -std=c++23 -Ofast main.cpp; time ./a.out 2000000000 l
1000000001000000000

real	0m0,520s
user	0m0,519s
sys	0m0,001s

% g++-14 -std=c++23 -Ofast main.cpp; time ./a.out 2000000000 c
1000000001000000000

real	0m0,458s
user	0m0,457s
sys	0m0,001s