"рдЖрдзреБрдирд┐рдХ" рд╕реА ++: рд╡рд┐рд▓рд╛рдк рдХреЗ рд╕рд╛рде рдПрдХ рд╡рд┐рд▓рд╛рдк рд╕рддреНрд░

рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреА рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд╡рд┐рдЪрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде, рдкрд╛рда рдХреА рдПрдХ рд▓рдВрдмреА рджреАрд╡рд╛рд░ рд╣реЛрдЧреАред рдореБрдЦреНрдп рд╡рд┐рдЪрд╛рд░:


  1. C ++ рдореЗрдВ, рд╕рдВрдХрд▓рди рд╕рдордп рдмрд╣реБрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ,
  2. рдЕрдиреБрдХреВрд▓рди рдХреЗ рдмрд┐рдирд╛ рдкреНрд░рджрд░реНрд╢рди рдХрд╛ рдирд┐рд░реНрдорд╛рдг рднреА рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ,
  3. рд╕рдВрдЬреНрдЮрд╛рдирд╛рддреНрдордХ рднрд╛рд░ рдФрд░ рднреА рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред рдореИрдВ рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЪрд░реНрдЪрд╛ рдирд╣реАрдВ рдХрд░реВрдВрдЧрд╛, рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдореБрдЭреЗ рдЧреВрдВрдЧрд╛ рдорд╣рд╕реВрд╕ рдХрд░рддреА рд╣реИ, рддреЛ рдореБрдЭреЗ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдирд╣реАрдВ рд╣реИ, рдпрд╣ рдмрд╣реБрдд рдХрдо рдкреНрдпрд╛рд░ рдХрд░рддрд╛ рд╣реИред C ++ рдореЗрд░реЗ рд╕рд╛рде рд▓рдЧрд╛рддрд╛рд░ рдРрд╕рд╛ рдХрд░рддрд╛ рд╣реИ ред

C ++ 20 рд░реЗрдВрдЬ рдкрд░ рдПрд░рд┐рдХ рдиреАрдмреНрд▓рд░ рдХреЗ рд╕реНрдЯреИрдВрдбрд░реНрдб рд░реЗрдВрдЬреНрд╕ рдмреНрд▓реЙрдЧ рдкреЛрд╕реНрдЯ рдиреЗ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдкреВрд░реЗ рдЯреНрд╡рд┐рдЯрд░ рдмреНрд░рд╣реНрдорд╛рдВрдб рдХрд╛ рдЪрдХреНрдХрд░ рд▓рдЧрд╛рдпрд╛, рд╕рд╛рде рд╣реА рдЖрдзреБрдирд┐рдХ рд╕реА ++ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ-рддреЛ-рднрджреНрджреА рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ (рдЗрд╕реЗ рд╣рд▓реНрдХреЗ рдврдВрдЧ рд╕реЗ рдбрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП!) рдХрд╛ рдПрдХ рдЧреБрдЪреНрдЫрд╛ред



рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдореИрдВрдиреЗ рднреА рдпреЛрдЧрджрд╛рди рджрд┐рдпрд╛ рд╣реИ ( рд▓рд┐рдВрдХ ):


рд╕реА ++ 20 рд░реИрдВрдХ рдкрд░ рдкрд╛рдпрдерд╛рдЧреЙрд░рд┐рдпрди рдЯреНрд░рд╛рдЗрдПрд▓реНрд╕ рдХрд╛ рдпрд╣ рдЙрджрд╛рд╣рд░рдг, рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рд░рд╛рдХреНрд╖рд╕реА рджрд┐рдЦрддрд╛ рд╣реИред рдФрд░ рд╣рд╛рдВ, рдореИрдВ рд╕рдордЭрддрд╛ рд╣реВрдВ рдХрд┐ рд░реЗрдВрдЬ рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддреА рд╣реИрдВ, рдЕрдиреБрдорд╛рди рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдЗрд╕реА рддрд░рд╣ред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЙрджрд╛рд╣рд░рдг рдбрд░рд╛рд╡рдирд╛ рд╣реИред рдХрд┐рд╕реА рдХреЛ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реЛрдЧреА?

рдЖрдЗрдП рдХрдЯреМрддреА рдХреЗ рддрд╣рдд рдЗрд╕ рд╕рдм рдкрд░ рдХрд░реАрдм рд╕реЗ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВред



рдпрд╣ рд╕рдм рдХреБрдЫ рдирд┐рдпрдВрддреНрд░рдг рд╕реЗ рдмрд╛рд╣рд░ рд╣реЛ рдЧрдпрд╛ (рдПрдХ рд╕рдкреНрддрд╛рд╣ рдмрд╛рдж рднреА, рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ рдЗрд╕ рдзрд╛рдЧреЗ рдХреЗ рдкреЗрдбрд╝ рдореЗрдВ рдЙрдбрд╝рдирд╛ рдЬрд╛рд░реА рд░рд╣реАрдВ!)ред


рдЕрдм, рдореБрдЭреЗ рдЕрдкрдиреЗ рд▓реЗрдЦ рдХреЗ рд╕рд╛рде рд╢реБрд░реБрдЖрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрд░рд┐рдХ рд╕реЗ рдорд╛рдлреА рдорд╛рдВрдЧрдиреА рд╣реЛрдЧреА; рдпрд╛рд░реЛрд╕реНрд▓рд╛рд╡рдирд╛ рдХрд╛ рдореЗрд░рд╛ рд░реЛрдирд╛ рдореБрдЦреНрдп рд░реВрдк рд╕реЗ "рд╕реА ++ рдХреА рд╕рд╛рдорд╛рдиреНрдп рд╕реНрдерд┐рддрд┐" рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реЛрдЧрд╛ред рдПрдХ рд╕рд╛рд▓ рдкрд╣рд▓реЗ рддреИрдпрд╛рд░ рдХрд┐рдП рдЧрдП рдореБрдЯреНрдареА рднрд░ gamedev рдмреВрд╕реНрдЯ рдореЗрдВ рдПрдХ рддрд░рд╣ рд╕реЗ Boost.Geometry рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдореЗрдВ рднрд╛рдЧ рдЧрдпрд╛, рдФрд░ рдпрд╣реА рдмрд╛рдд C ++ рдкрд╛рд░рд┐рд╕реНрдерд┐рддрд┐рдХреА рддрдВрддреНрд░ рдХреЗ рджрд░реНрдЬрдиреЛрдВ рдЕрдиреНрдп рдкрд╣рд▓реБрдУрдВ рдХреЗ рд╕рд╛рде рднреА рд╣реБрдИред


рд▓реЗрдХрд┐рди рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ, рд╕рдВрд╡реЗрджрдирд╢реАрд▓ рд╡рд╛рд░реНрддрд╛рд▓рд╛рдк рдЖрджрд┐ рдХреЗ рд▓рд┐рдП рдЯреНрд╡рд┐рдЯрд░ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫреА рдЬрдЧрд╣ рдирд╣реАрдВ рд╣реИред рд╣рдореЗрдВ рдпрд╣рд╛рдБ рдФрд░ рдЕрднреА рд╡рд┐рдЪрд╛рд░ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛!


рдкрд╛рдпрдерд╛рдЧреЙрд░рд┐рдпрди рдЯреНрд░рд┐рдкрд▓ рд╕реА ++ 20 рдХреА рд╢реИрд▓реА рдореЗрдВ


рдПрд░рд┐рдХ рдХреЗ рдкреЛрд╕реНрдЯ рд╕реЗ рдкреВрд░рд╛ рдЙрджрд╛рд╣рд░рдг рдкрд╛рда рд░рдЦреЗрдВ:


//     C++20.
//    N  .
#include <iostream>
#include <optional>
#include <ranges>   //   !

using namespace std;

// maybe_view    0  1 
template<Semiregular T>
struct maybe_view : view_interface<maybe_view<T>> {
  maybe_view() = default;
  maybe_view(T t) : data_(std::move(t)) {
  }
  T const *begin() const noexcept {
    return data_ ? &*data_ : nullptr;
  }
  T const *end() const noexcept {
    return data_ ? &*data_ + 1 : nullptr;
  }
private:
  optional<T> data_{};
};

// "for_each"   , 
//       ,
//        .
// (   constrained lambdas  C++20.)
inline constexpr auto for_each =
  []<Range R,
     Iterator I = iterator_t<R>,
     IndirectUnaryInvocable<I> Fun>(R&& r, Fun fun)
        requires Range<indirect_result_t<Fun, I>> {
      return std::forward<R>(r)
        | view::transform(std::move(fun))
        | view::join;
  };

// "yield_if"  bool  , 
//    0  1 .
inline constexpr auto yield_if =
  []<Semiregular T>(bool b, T x) {
    return b ? maybe_view{std::move(x)}
             : maybe_view<T>{};
  };

int main() {
  //     :
  using view::iota;
  auto triples =
    for_each(iota(1), [](int z) {
      return for_each(iota(1, z+1), [=](int x) {
        return for_each(iota(x, z+1), [=](int y) {
          return yield_if(x*x + y*y == z*z,
            make_tuple(x, y, z));
        });
      });
    });

    //   10 
    for(auto triple : triples | view::take(10)) {
      cout << '('
           << get<0>(triple) << ','
           << get<1>(triple) << ','
           << get<2>(triple) << ')' << '\n';
  }
}

, , ┬лGetting Lazy with C++┬╗, N :


void printNTriples(int n)
{
    int i = 0;
    for (int z = 1; ; ++z)
        for (int x = 1; x <= z; ++x)
            for (int y = x; y <= z; ++y)
                if (x*x + y*y == z*z) {
                    printf("%d, %d, %d\n", x, y, z);
                    if (++i == n)
                        return;
                }
}

:


, . , , ? , ?

(list comprehensions) . , - , C++ , - Haskell . C++20 , . .


C++


, , C/C++ (┬л┬╗ тАФ , ┬л, ┬╗, ). , :


// simplest.cpp
#include <time.h>
#include <stdio.h>

int main()
{
    clock_t t0 = clock();

    int i = 0;
    for (int z = 1; ; ++z)
        for (int x = 1; x <= z; ++x)
            for (int y = x; y <= z; ++y)
                if (x*x + y*y == z*z) {
                    printf("(%i,%i,%i)\n", x, y, z);
                    if (++i == 100)
                        goto done;
                }
    done:

    clock_t t1 = clock();
    printf("%ims\n", (int)(t1-t0)*1000/CLOCKS_PER_SEC);
    return 0;
}

: clang simplest.cpp -o outsimplest. 0.064 , 8480 , 2 ( : 2018 MacBookPro; Core i9 2.9GHz; тАФ Xcode 10 clang).


(3,4,5)
(6,8,10)
(5,12,13)
(9,12,15)
(8,15,17)
(12,16,20)
(7,24,25)
(15,20,25)
(10,24,26)
...
(65,156,169)
(119,120,169)
(26,168,170)

! , (┬лDebug┬╗) ; (┬лRelease┬╗): clang simplest.cpp -o outsimplest -O2. 0.071 (8480 ), 0 ( , clock()).


, , . ┬л ┬╗ ( , ┬л┬╗ ┬л ┬╗ ). , , -, N , .


тАФ , , . :


// simple-reusable.cpp
#include <time.h>
#include <stdio.h>

struct pytriples
{
    pytriples() : x(1), y(1), z(1) {}
    void next()
    {
        do
        {
            if (y <= z)
                ++y;
            else
            {
                if (x <= z)
                    ++x;
                else
                {
                    x = 1;
                    ++z;
                }
                y = x;
            }
        } while (x*x + y*y != z*z);
    }
    int x, y, z;
};

int main()
{
    clock_t t0 = clock();

    pytriples py;
    for (int c = 0; c < 100; ++c)
    {
        py.next();
        printf("(%i,%i,%i)\n", py.x, py.y, py.z);
    }

    clock_t t1 = clock();
    printf("%ims\n", (int)(t1-t0)*1000/CLOCKS_PER_SEC);
    return 0;
}

. 168 , .


pytriples, next() ; , . , .


, , for- , , , . , , ( ), .


C++ - , , , , ┬л┬╗ ( ┬лRanges, Code Quality, and the Future of C++┬╗); ( , C++ ):


generator<std::tuple<int,int,int>> pytriples()
{
    for (int z = 1; ; ++z)
        for (int x = 1; x <= z; ++x)
            for (int y = x; y <= z; ++y)
                if (x*x + y*y == z*z)
                    co_yield std::make_tuple(x, y, z);
}

C++


C++20 ? , :


auto triples =
    for_each(iota(1), [](int z) {
        return for_each(iota(1, z+1), [=](int x) {
            return for_each(iota(x, z+1), [=](int y) {
                return yield_if(x*x + y*y == z*z,
                    make_tuple(x, y, z));
                });
            });
        });

. , , , . , C++ , , C++ (┬л ? , !┬╗) тАФ . return- , , , .


, , .


, , , C++, , :


template<Semiregular T>
struct maybe_view : view_interface<maybe_view<T>> {
  maybe_view() = default;
  maybe_view(T t) : data_(std::move(t)) {
  }
  T const *begin() const noexcept {
    return data_ ? &*data_ : nullptr;
  }
  T const *end() const noexcept {
    return data_ ? &*data_ + 1 : nullptr;
  }
private:
  optional<T> data_{};
};
inline constexpr auto for_each =
  []<Range R,
     Iterator I = iterator_t<R>,
     IndirectUnaryInvocable<I> Fun>(R&& r, Fun fun)
        requires Range<indirect_result_t<Fun, I>> {
      return std::forward<R>(r)
        | view::transform(std::move(fun))
        | view::join;
  };
inline constexpr auto yield_if =
  []<Semiregular T>(bool b, T x) {
    return b ? maybe_view{std::move(x)}
             : maybe_view<T>{};
  };

, - , - , Perl , Brainfuck тАФ , . C++ 20 . , , , .


, , maybe_view, for_each, yield_if тАФ ┬л ┬╗, ; , тАж .


┬л ┬╗


:



, , C++, , .


C++20 , , range-v3 ( ), .


// ranges.cpp
#include <time.h>
#include <stdio.h>
#include <range/v3/all.hpp>

using namespace ranges;

int main()
{
    clock_t t0 = clock();

    auto triples = view::for_each(view::ints(1), [](int z) {
        return view::for_each(view::ints(1, z + 1), [=](int x) {
            return view::for_each(view::ints(x, z + 1), [=](int y) {
                return yield_if(x * x + y * y == z * z,
                    std::make_tuple(x, y, z));
            });
        });
    });

    RANGES_FOR(auto triple, triples | view::take(100))
    {
        printf("(%i,%i,%i)\n", std::get<0>(triple), std::get<1>(triple), std::get<2>(triple));
    }

    clock_t t1 = clock();
    printf("%ims\n", (int)(t1-t0)*1000/CLOCKS_PER_SEC);
    return 0;
}

0.4.0 (9232b449e44 22 2018 ), clang ranges.cpp -I. -std=c++17 -lc++ -o outranges. 2.92 , 219 , 300 .


, . (clang ranges.cpp -I. -std=c++17 -lc++ -o outranges -O2) 3.02 , 13976 , 1 . , , .


.


тАФ C++


2.85 , ┬л C++┬╗.


, ┬л 3 ┬╗ тАФ , . CPU . , clang (SQLite) , 220 ? 0.9 . , 5 ?


++ , . ? , - (Chromium, Clang/LLVM, UE4, ). , C++, , , , . , , C++ , , , , .


┬л ┬╗ #include, . , C++ /.


range-v3 1.8 , ! , 30 , 102 . ┬л C++┬╗ 720 .


/ ! тАФ , . . precompiled header (pch.h : #include <range/v3/all.hpp>, pch.h, PCH: clang -x c++-header pch.h -I. -std=c++17 -o pch.h.pch, pch: clang ranges.cpp -I. -std=c++17 -lc++ -o outranges -include-pch pch.h.pch). 2.24 . , PCH 0.7 . 2.1 , , C++ :(


тАФ


150 . , 2 3 . , 10 . , ? ?


, , , . ; , ( ). , , , , 10 100 , ┬л┬╗. , . , , ┬л┬╗ ┬л┬╗. , 2 .


, (-O2 clang) ┬л C++┬╗тАж , , ┬лzero cost abstractions┬╗, - . , .


тАФ ! , , . , . - , . , , .


Arseny Kapoulkine ┬лOptimizing OBJ loader┬╗ YouTube, , 10 , STL (). () , STL Microsoft .


, ┬лSTL тАФ ┬╗; STL, (EASTL libc++ ), - Microsoft STL , ┬л ┬╗.


, , ! тАФ ┬лSTL ┬╗, , - . (, STL, , C++, ).



┬л ┬╗ C#:


using System;
using System.Diagnostics;
using System.Linq;

class Program
{
    public static void Main()
    {
        var timer = Stopwatch.StartNew();
        var triples =
            from z in Enumerable.Range(1, int.MaxValue)
            from x in Enumerable.Range(1, z)
            from y in Enumerable.Range(x, z)
            where x*x+y*y==z*z
            select (x:x, y:y, z:z);
        foreach (var t in triples.Take(100))
        {
            Console.WriteLine($"({t.x},{t.y},{t.z})");
        }
        timer.Stop();
        Console.WriteLine($"{timer.ElapsedMilliseconds}ms");
    }
}

, . C#:


var triples =
    from z in Enumerable.Range(1, int.MaxValue)
    from x in Enumerable.Range(1, z)
    from y in Enumerable.Range(x, z)
    where x*x+y*y==z*z
    select (x:x, y:y, z:z);

C++:


auto triples = view::for_each(view::ints(1), [](int z) {
    return view::for_each(view::ints(1, z + 1), [=](int x) {
        return view::for_each(view::ints(x, z + 1), [=](int y) {
            return yield_if(x * x + y * y == z * z,
                std::make_tuple(x, y, z));
        });
    });
});

, . ? , C# LINQ :


var triples = Enumerable.Range(1, int.MaxValue)
    .SelectMany(z => Enumerable.Range(1, z), (z, x) => new {z, x})
    .SelectMany(t => Enumerable.Range(t.x, t.z), (t, y) => new {t, y})
    .Where(t => t.t.x * t.t.x + t.y * t.y == t.t.z * t.t.z)
    .Select(t => (x: t.t.x, y: t.y, z: t.t.z));

C#? Mac, Mono ( C#) 5.16 mcs Linq.cs 0.20 . ┬л C#┬╗ 0.17 .


, LINQ 0.03 . 3 C++ тАФ 100 !


, ?


, - .


, Unity , ┬л Boost ┬╗. , , , - Boost.Asio, , , asio.h <windows.h>, .


STL. , , EASTL тАФ , /, , . - , (unordered_map STL , separate chaining; - ). .


.


, ( , ) , ┬л┬╗ C++ , ( ! ). , ┬л ┬╗ , ( , ! ).


, ( ) , , ┬л ┬╗ . () , , тАО(я╛Йр▓ечЫКр▓ея╝Йя╛Йя╗┐ тФ╗тФБтФ╗, ┬л, , ┬╗. : ┬л, - ?┬╗. : ┬л, !┬╗. (, , - ). , C C++, , . ; , ┬л тАФ ┬╗, тАФ ; .


, C++, . , ┬л тАФ ┬╗, ┬л , , ┬╗.


C++?


. , ┬л , , ┬╗. , C++ , , !


- , , C++ ┬л┬╗ .


C/C++. , - 16 . Boost, : ┬л, , !┬╗. , .


, , Formula 1 . ? . ? . , ? ! 99% , ? .


:


, . ┬л ┬╗. , C++ 1) 2) , , , , , . 2.

, , C++ , , . . ( ) . ( EASTL). , C++ , (Jai) (Rust, C#).



, , ┬л ┬╗ , тАФ . , , , , , , . ; , - , тАФ . !


, - , C++, STL . - , .


, . тАФ .


, , , . , , , , , .


, - , ? ┬л┬╗ ┬л ┬╗, . , ? // тАФ . , ┬л, ┬╗, .


  • ┬л , , ┬╗ тАФ !
  • ┬л , , , ┬╗ тАФ !
  • ┬л, ┬╗ тАФ !
  • ┬л , , , ┬╗ тАФ , , .

┬л , , C++┬╗, . , ┬л Boost!┬╗ C++, , Boost тАФ - .


, , . C C++ , ( Rust, ). C++, , , , , .


, , тАФ . C++, ┬л ┬╗ ( - ); - . , ; , . , , - , ┬лC++ тАФ , ┬╗, , .


, (C++11/14/17) C++ тАФ , , constexpr if , . , , STL ( , ), , , ///тАж , , , .


. 19-20 C++ Russia 2019. , . тАФ Arno Sch├╢dl, CTO Think-Cell, ┬лText Formatting For a Future Range-Based Standard Library┬╗. , ? . , ( ).

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


All Articles