CppCon 2016: Jason Turner “Practical Performance Practices"

Поделиться
HTML-код
  • Опубликовано: 1 окт 2016
  • CppCon.org
    -
    Presentation Slides, PDFs, Source Code and other presenter materials are available at: github.com/cppcon/cppcon2016
    -
    In the past 6 years ChaiScript's performance has been improved by nearly 100x. This was not accomplished by adding a virtual machine or performing dynamic recompilation. Instead, these increases have been accomplished by moving to more simple, cleaner, idiomatic C++ and by following some simple rules. We will outline these concepts with examples for how they both simplified code while improving performance.
    -
    Jason Turner
    Developer, Trainer, Speaker
    Host of C++Weekly / jasonturner-lefticus , Co-host of CppCast cppcast.com, Co-creator and maintainer of the embedded scripting language for C++, ChaiScript chaiscript.com, and author and curator of the forkable coding standards document cppbestpractices.com. I'm available for contracting and onsite training.
    -
    Videos Filmed & Edited by Bash Films: www.BashFilms.com
    *-----*
    Register Now For CppCon 2022: cppcon.org/registration/
    *-----*

Комментарии • 74

  • @seancpp
    @seancpp 2 года назад +31

    Jason Turner, Herb Sutter, Scott Meyers, Venkat Subramaniam, Kate Gregory, and Dylan Beattie I think are some of the greatest technical speakers of our day. I thoroughly enjoy every talk I've seen by each of those people

    • @pankajthapa1417
      @pankajthapa1417 Год назад +1

      Arther o'dwyer, mayer scott, Klaus Iksagberg, Dimitri Nesteruk,

    • @virtualspecies
      @virtualspecies Год назад +2

      Jason's awesome - after watching his constexpr CppCon talk I'm now going through all his presentations;
      totally dig his style & you're certain to take away a couple of things from *every* talk 👍

    • @xealit
      @xealit Месяц назад

      Arthur O'dwyer is pretty good

  • @wCupOfTea
    @wCupOfTea 7 лет назад +86

    Jason Turner has one the best talks this year.

    • @SAFAR04
      @SAFAR04 7 лет назад +7

      Yeah for sure. Hope he will do more next time.

    • @jostein6581
      @jostein6581 7 лет назад +6

      Definitely agree on that.

    • @victornoagbodji
      @victornoagbodji 7 лет назад +2

      yep

    • @EgD996
      @EgD996 7 лет назад +2

      yes, and I also like your cppcast

  • @CharIie83
    @CharIie83 6 лет назад +5

    I love how he is honest about his findings. Most people would try to forget and never mention again.

  • @blackmav5
    @blackmav5 7 лет назад +5

    Thank you Jason Turner for your talks. Compared to the time I spent watching it and what I get out of it, even if it just a repetition, really great! One of the best even.

  • @seditt5146
    @seditt5146 4 года назад +33

    13:30 "Don't Const!" .... I like the way he thinks, ima do more of that ;)

  • @n3whous3
    @n3whous3 7 лет назад +13

    the c++17 c64 was an awesome talk, and this too

  • @PatrickKellyLoneCoder
    @PatrickKellyLoneCoder 5 лет назад +17

    Here's a tip for programming language snippets inside of presentations:
    Write out the code instead of taking a screen shot. Color that code as an editor would.
    Sometimes you'll need to remove the slide title; that's fine, the point is the code example. The title can be put on a title slide then move over to the code slide.

  • @lextorn92
    @lextorn92 4 года назад +2

    11:22 if you spawn more threads on val of uncached Int, you can be calculating more than once, if context switch will occur after entering if and before setting is_calculated.

    • @fatty-it-man
      @fatty-it-man 3 года назад +1

      of course, it must be done with mutex. exactly the same as in Singleton pattern

  • @musicalfringe
    @musicalfringe 4 года назад

    This reminded me of a few habits I ingrained so long ago that I don't even notice them any more.

  • @mikevasiljevs412
    @mikevasiljevs412 7 лет назад +13

    @13:30 "don't _const_"?

  • @korcanucar5395
    @korcanucar5395 6 лет назад +1

    Practical Performance Practices - may be you need to apply some principles to the title of the presentation, as well :) great talk !

  • @Tau-qr7f
    @Tau-qr7f 2 года назад

    this talk is super helpful for me

    • @CppCon
      @CppCon  2 года назад

      Very pleased to hear that the presentation was helpful!

  • @thePrzemko17
    @thePrzemko17 7 лет назад

    40:00 anyone can explain me why there will be only one shared_ptr created? I tought the vector is constructed of shared pointers, and there are 4 objects.

    • @TrueWodzu
      @TrueWodzu 5 лет назад +1

      The question was about number of instantiations of template. Since we use only one type which is int, only one instance of template will be created.

  • @robingreen7920
    @robingreen7920 2 года назад +1

    thanks

  • @AxelStrem
    @AxelStrem 7 лет назад

    I thought std::make_shared is intrusive (1 allocation for both control block and the object)

  • @dimaredko2091
    @dimaredko2091 7 лет назад +2

    @7:50 Jason showed string with const modifier and stated that "const" may increase performance. I didn't get that? I thought that during assignment construction only corresponding constructor will be called, isn't it? and if so how const is helpful here

    • @TrueWodzu
      @TrueWodzu 5 лет назад

      You are right, const is not helpful at all in this example. But maybe the example is too small and compiler sees that string without const is not modified anyway so it is const qualified internally anyway.

    • @masheroz
      @masheroz Год назад

      If the compiler knows that a variable is never going to be changed, it can do other optimisations in other circumstances

  • @alexeyfadieiev4070
    @alexeyfadieiev4070 10 месяцев назад +1

    I didn't get on 40:00 , why many instantiations of shared pointers influence on compile RAM and time, but unique_ptr does not? Could someone please explain this point? Thank you.

    • @MrBufellow
      @MrBufellow 5 месяцев назад

      I believe unique pointers just manage the scope of the pointer and don't let you move it outside the scope. They delete themselves upon the scope ending. With shared pointers, the references have to be kept track of and incremented and decremented every time you move it around.

  • @bemo6434
    @bemo6434 5 месяцев назад

    What I learned from this talk: don't use red syntax highlighting on a gray background!

  • @mrlithium69
    @mrlithium69 7 лет назад +2

    That stuff about Base/Derived class redefining the virtual destructor disables move operations. and the solution to type all those default rules out.. ugh i cant believe that is the solution

    • @NXTangl
      @NXTangl 5 лет назад +2

      C++ is actually surprisingly bad at being a fast language.

  • @billw2461
    @billw2461 7 лет назад +6

    Regarding unique_ptr vs shared_ptr (ruclips.net/video/uzF4u9KgUWI/видео.html):
    I do not get comparable results in MSVC. shared_ptr ends up (slightly) faster to compile (with default compiler settings under debug). EXE is still bigger though, and I'm sure the performance implications still apply.

  • @dresnyd
    @dresnyd 7 лет назад +9

    20:26 If the string 's' was const then how would you move it.

    • @noamrodrik3776
      @noamrodrik3776 6 лет назад +1

      You can move it, because it is being copied to the struct S via the constructor's parameter, which is copied by value.

    • @Henrik0x7F
      @Henrik0x7F 6 лет назад +4

      Peterolen it's first copied and then moved from the copy

    • @oleghab2
      @oleghab2 4 года назад

      The fact is you actually can make two constructors to ensure copy elision
      struct A {
      std::string a;
      A(std::string const& a_) : a(a_) {}
      A(std::string && a_) : a(std::move(a_)) {}
      };

  • @yyyy-uv3po
    @yyyy-uv3po Год назад

    I thought that lambda were implemented by std::function and binding under the hood, how come they don't lead to any overhead ?
    I mainly use lambda for storing callbacks

    • @user-nw8pp1cy8q
      @user-nw8pp1cy8q Год назад +4

      Nope. It is most often implemented as new anonymous class with overriden call operator. So each lambda has unique type.

  • @TV20
    @TV20 Год назад

    26:26 why function accepting Base by reference as passed it to pointer?

    • @masheroz
      @masheroz Год назад

      He explained that was a bug.

  • @IndellableHatesHandles
    @IndellableHatesHandles Год назад

    Storing a shared_ptr in a class so that you can have a getter for a complicated data structure is the only time I ever use shared_ptr.

  • @MrZapper1960
    @MrZapper1960 2 года назад +1

    Wow this one took off at 3:00

  • @MrAbrazildo
    @MrAbrazildo 7 лет назад

    - 9:00, wouldn't it be better coded as:
    const std::string s (std::move (std::string ("long string is mod ") + ('0' + std::rand() % 4))); ?
    - 13:25, couldn't you had inline val() and the constructor?
    - 25:40, is that valid for explicit casts of dynamic_cast too?

    • @user-nw8pp1cy8q
      @user-nw8pp1cy8q Год назад

      There is no point of moving temporary because it is already rvalue. On contrary, using std::move can prevent copy elision and be slower.

  • @AxelStrem
    @AxelStrem 7 лет назад +9

    great talk, but I still don't see how move/copy semantics can be useful in polymorphic classes. Like, if you want to move the polymorphic object, you pretty much just reassign the pointer; and for copies you'd need a virtual clone method. As the person @17:30 (is trying to) say, enabling copy/move just allows you to implicitly slice objects, hardly a good practice

  • @n3whous3
    @n3whous3 7 лет назад +7

    just one comment for 11:30 - even the values became atomic, de method should be atomic itself. The variable usages could get inconsistent because you didn't block the whole function. If you know what I mean

  • @vivekatbitm
    @vivekatbitm 5 лет назад

    Doesn't IIFE has cost and should it be used just for const initialisation as const is just for code maintainability n has no performance gains?

    • @Swedishnbkongu
      @Swedishnbkongu 2 года назад +1

      At even O1 optimizations it should be inlined

  • @dawikur
    @dawikur 7 лет назад +11

    at 12:34 there is still data race

    • @varunnagp3903
      @varunnagp3903 7 лет назад

      Yes, atomics dont quite solve race condition

    • @vonkruel
      @vonkruel 7 лет назад

      I don't see it.

    • @vonkruel
      @vonkruel 7 лет назад +2

      I usually think of a data race as a bug. In this case I'd say there's no problem with the code. Whatever we do to prevent the value being calculated multiple times is probably going to hurt performance.

    • @dawikur
      @dawikur 7 лет назад +2

      You are right, but at this point it might we worth mentioning that using multiple atomic's can still be dangerous.

    • @fob3476
      @fob3476 2 года назад

      I think there's a race condition (atoi() can be called multiple times), but no data race (no undefined behavior)

  • @lincolnsand5127
    @lincolnsand5127 4 года назад +2

    He should do `std::stoi` instead of `std::atoi(string.c_string())`

    • @MuqsitNawaz
      @MuqsitNawaz 4 года назад +1

      I'd rather prefer std::from_chars (since C++17).

  • @vertigo6982
    @vertigo6982 5 лет назад

    24:20 incrementing REFERENCE count by passing by VALUE? Not passing by REFERENCE?

    • @kebien6020
      @kebien6020 5 лет назад +3

      yes
      shared_ptr keeps a refcount which is just a number that is incremented atomically every time a new shared_ptr is created from copying another one and decremented when a shared_ptr is destructed. When the refcount reaches 0 the object owned by the pointer(s) is destroyed.
      When you pass the shared_ptr by value you are copying it so it increments the refcount, if you instead pass the shared_ptr by reference you are essentially passing a pointer to the shared_ptr object and that does not count as copying the shared_ptr.
      Passing a shared_ptr by value means sharing the ownership of the underlying object, passing it by reference does not entail sharing and its usually an error. As shown in the slides you most likely just want to .get() the raw pointer and pass it.

  • @michaeldunlavey6015
    @michaeldunlavey6015 Год назад

    All these talks are fine, but I'm always struck by what's missing. What's missing is _diagnosis._ _How do you know what to fix?_
    There's a bone-simple method I've used for half a century, and it resembles the _poor man's profiler._ I don't do it for economic reasons. I do it because _it actually works,_ where profilers don't. I'm not saying profilers don't measure stuff. I'm saying _they don't tell you much to fix,_ and if you're a typical programmer, you're happy to hear that.
    All it requires is the ability to take a SMALL NUMBER of samples of the call stack, such as with a debugger. AHEM. That's CALL STACK, where you can see each line, not just PROGRAM COUNTER, which is all the optimizer cares about. Look for calls you could avoid.
    You're looking for code that could be improved, which is kind of like a bug, but not a correctness bug. After you fix it, you realize it was a bug, but only in the sense that it was doing unnecessary stuff - a speed bug.
    If a speed bug is big enough to be worth fixing, i.e. if the time that could be saved by fixing it, is more than 10% (typically it is 20%-90%), then you WILL SEE IT two or more times in a small number of samples. I usually take between 5 and 20 samples. If you see it just once, that could be by chance. But if you see it twice, you can be sure it's real.
    And, there is never just one speed bug. Usually there are several, in a range of sizes. Here's the thing: _removing one magnifies the others, so it takes fewer samples to see them._ The minimum execution time you can get to is what's left over after they've all been removed, and that can be _orders of magnitude_ smaller than what you started with.
    Just a few typical speed bugs are:
    - Calling *new* or *delete* when a prior object could just be re-used.
    - Calling *pushback* which deletes, reallocates, and copies an array just to make it 1 element bigger.
    - I/O time formatting or writing lines to a log file that nobody reads.
    - I/O time reading a DLL file to get a string translation resource, when the string doesn't need to be translated.
    - Calling an array-indexing function to index an array, to make sure the index is within range, when you know the index cannot be out of range.
    - Calling *==* between strings to check program state, when integers could be used.
    ... there is no limit to the ways time can be wasted.

  • @sabetaytoros4123
    @sabetaytoros4123 7 лет назад

    10::34 Don"t do more than you have to
    class (Int) {
    Int(std::string t_s) : s(t_s) , value(std::atoi(s)) {};
    std::string s;
    int value;
    } ;
    If you calculate the value in the constructor you dont"t have to declare is the variable isCalculated;
    And you dont need to call the Val function. So the function Val is obselete.

  • @Elbrasch
    @Elbrasch 7 лет назад +2

    at 28:50 using '
    ' instead of std::endl, that makes my code linux locked, because windows uses '

    '. Not something that will cause me problems most of the times, but something that should be mentioned anyways, because portability should be something one should keep in mind.,

    • @hkmix
      @hkmix 7 лет назад +21

      '
      ' is portable on the commandline, AFAIK. When you're just printing to stdout, '
      ' will always give you what you expect. You'll only have a problem with Notepad, but you can also open the stream in text mode in that case, which does platform-specific conversions.

    • @kaboissonneault
      @kaboissonneault 7 лет назад +8

      Jason Turner mentioned this in one of his C++ weekly videos on youtube. '
      ' is portable

    • @MrAbrazildo
      @MrAbrazildo 7 лет назад

      Nope. Windows uses '
      ' (LF); and Linux, "
      " (CRLF). I saw that a bunch of times, using hex editor.
      If your app. expected to find '
      ', it may crash if it was important.

    • @hkmix
      @hkmix 7 лет назад +15

      You actually have those flipped (Windows uses CRLF, modern *NIX uses LF). Unless you're in a file, std::cout

    • @bloopbleep7082
      @bloopbleep7082 4 года назад +1

      iostreams are formatted IO. That means they do newline conversions, and possibly other conversions. Also on Windows the newline sequence is
      .

  • @ashrasmun1
    @ashrasmun1 7 лет назад

    I'm a bit puzzled, because at lacture about "Practical Performance Practices" people call out bugs on so many slides...

    • @TrueWodzu
      @TrueWodzu 5 лет назад +11

      "So many slides" is actualy a whopping amount of two and it does not influence in anyway the message they are conveying.

  • @programmingeverything
    @programmingeverything 7 лет назад +5

    So many bugs on your slide