Outpost Universe Forums

Off Topic => Computers & Programming General => Topic started by: Vagabond on November 23, 2019, 09:44:28 PM

Title: Preferring range based algorithms over loops
Post by: Vagabond on November 23, 2019, 09:44:28 PM
When checking out CppCheck, a static code analysis tool, it flagged several of my lops and recommended switching them to various std library algorithms (for_each, find_if, etc). Most of these recommendations would require writing a custom function or in place lambda expression to operate.

I've found lambda expressions very useful on the occasion that I've ventured into using them. The syntax is difficult to remember and review in other's code unless one uses them consistently (well for me anyways, others may be better at memorizing than I am).

The arguments for using the algorithms over loops goes something along the lines that it makes your code easier to read and offers efficiency gains over hand coding loops. I was curious if some of the other c++ programmers found this true. It could be a good excuse for me to practice lambda expressions more, but I tend to avoid them as I feel it makes the code harder to read.

Random Google articles agreeing with the static code check analysis on the subject

Title: Re: Preferring range based algorithms over loops
Post by: leeor_net on November 23, 2019, 09:53:06 PM
One of the benefits is if you're using standard containers, the best option for iterating over that container is chosen using a range based. It also seems to be the general guidelines for coding best practices. I haven't done any sort of metrics with them so I can't attest to performance differences but I do know I like how the code looks when I use them. Much easier to deal with.
Title: Re: Preferring range based algorithms over loops
Post by: Hooman on November 25, 2019, 05:54:46 PM
Some interesting points concerning correctness and efficiency there.

I guess one of the problems I have is it can be hard to reason about correctness and efficiency of standard library algorithms, since it's not clear how they are implemented, or what guarantees or assumptions they provide. It often becomes a matter of looking up some documentation, and hoping they address the particular concern. Though the documentation is usually quite thorough, and the algorithms are usually quite good about both efficiency and correctness, so that's good.

I noticed the second article was quite dated. The publication year is 2001. I noticed this after they started talking about functors, and how the examples lacked any use of lambdas. Lambdas are functors. That's how they are implemented. Lambdas are just syntactic sugar to generate anonymous functors. Their use would have simplified some of those code examples. It probably would have also made them easier to read, module having to understand the lambda syntax.

I think people probably should use lambdas more often. They can be pretty awesome. It does make code a little harder to read for less experienced C++ programmers though.

In terms of going forward, I expect Ranges will change things quite drastically. Using the Ranges library, it should be possible to write (largely) loop free code, much like how std::unique_ptr and std::shared_ptr allow you to write new/delete free code. I recently watched a talk that showed a console printing calendar app written using Ranges that demonstrated that quite nicely:
CppCon 2015: Eric Niebler "Ranges for the Standard Library" (https://www.youtube.com/watch?v=mFUXNMfaciE)

It seems C++ is really (finally) starting to gain ground with expressing high level concerns in a simple manner. I'm liking where the future is heading.

On a somewhat related note, I watched another interesting talk about some of the costs of higher level abstractions:
CppCon 2019: Chandler Carruth “There Are No Zero-cost Abstractions” (https://www.youtube.com/watch?v=rHIkrotSwcc)
Title: Re: Preferring range based algorithms over loops
Post by: leeor_net on November 25, 2019, 06:17:41 PM
Without having read the last article, I will say at the very least that the general power of modern computers does negate a lot of the downsides of abstraction (e.g., when C# was new the overhead was a performance problem, something we don't really see anymore between the maturing of the language and the significant performance gains over the last 15 years or so).