Блог пользователя cjquines

Автор cjquines, история, 8 лет назад, По-английски

This is based on the GNU C++11 compiler on Codeforces. Results inconclusive.

I will be omitting discussion of input and output, which is well-known.

  • No significant performance difference between ranged fors (26322469, 26322507) and iterating over elements (26316124)
  • No significant performance difference between assignment with tie (26322531) and regular assignment (26316124)
  • No significant performance difference between emplace, emplace_back (26316124) and push, push_back (26322556)

It is well known that auto is compile-time, so there will be no performance difference.

  • Проголосовать: нравится
  • +35
  • Проголосовать: не нравится

»
8 лет назад, # |
  Проголосовать: нравится +16 Проголосовать: не нравится

First of all, thanks for research. I really don't know why you have so much downvotes, but I can't do more than one upvote :(

Now about results and my thoughts:

  • compilers usually convert for(auto smth : container) into iterating with iterator. As far as I know, vector's iterator in GCC is actually a pointer. And when you are using operator [] for vectors, you actually just add some value to pointer. So difference is predictably indistinguishable.

  • tie was made for using with tuples. And it is just a syntactic sugar for easy converting tuple to set of variables. I think GCC converts it to regular assignment

  • emplace and emplace_back are good for structures and classes with no copy constructors inside. Or if class has easy creating and hard copying constructors.

Ofc, it's just IMHO.

  • »
    »
    8 лет назад, # ^ |
      Проголосовать: нравится +15 Проголосовать: не нравится

    Yes, I checked the assembly code. Ranged fors are converted to iterators, and tie is converted to assignment, in GCC with -O2 switch at least.

  • »
    »
    8 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

    emplace and emplace_back also bring some syntactic sugar to the language. Compare vec.push_back(make_pair(a, b)) vs vec.push_back({a, b}) vs vec.emplace_back(a, b).

    • »
      »
      »
      8 лет назад, # ^ |
        Проголосовать: нравится +3 Проголосовать: не нравится

      It is shorter but not always clearly. I mean, it doesn't give you any information about container — what type it stores. Sometimes it isn't required, but sometimes it costs couple of minutes.

      • »
        »
        »
        »
        8 лет назад, # ^ |
        Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

        Couple of minutes sounds overestimated, but yes, you lose some information by using this version of emplace_back. However this version mostly used with pair and it's kind of clear in most cases.

      • »
        »
        »
        »
        8 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        it doesn't give you any information about container — what type it stores.

        Could you, please, give an example of such situation? I don't see a problem here.

        • »
          »
          »
          »
          »
          8 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится

          Something like this:

          @ Trying to understand some functions of inherited code

          @ After N hours of analysis you find method with 50+ lines of code

          @ Some bit operations, some methods, some attributes

          @ for (auto i : q) some_name.emplace_back(i.a, i.b, i.c)

          @ wtf is some_name and what does it store

          @ You are Marlin from "Finding Nemo" and some_name field is Nemo. But you have found it!

          @ mutable set<T> some_name;

          @ this class is template class and you have no idea what does some_name mean