-
August 19th, 2015, 11:22 AM
#16
Re: stl map of vectors
Originally Posted by tiliavirga
I personally prefer structure over logic and that's why the (benign) goto in my solution doesn't bother me at all.
I don't quite understand what you mean by "structure over logic" here though: isn't the structure entirely a logical structure?
One advantage of using the generic algorithm is that the abstraction provides the reader with immediate information, i.e., instead of parsing the loop to figure out what it does, the reader knows that the aim is to try and find something. The logical structure remains essentially the same, except that part of the details is hidden by an abstraction. In this particular case, an additional advantage is that now we only need to break from a non-nested loop, so the simple break does the job.
Originally Posted by tiliavirga
And if break is so disgusting
You are mistaken: the break (whether the keyword or simulated with goto because C++'s break does not allow breaking from within an inner loop out of an outer loop) is not disgusting. Rather, it is appropriate to the logic here, and in fact I notice that it is you who wrote the appropriately used goto in the first place.
Originally Posted by tiliavirga
why didn't you replace the outermost loop with a function too (say find_if).
I think that the range-based for loop would be sufficient. Using find_if would not necessarily improve the readability of the code because the predicate might not be simpler than the current loop body.
Instead, for abstraction, the entire code snippet could be moved to a separate function instead to abstract away the entire "want to know which PDN it belongs to" search logic.
Originally Posted by tiliavirga
That would remove also the remaning break from your code.
Removing a break just for the sake of removing a break, without improving the readability of the code, is a misguided approach.
-
August 19th, 2015, 11:23 AM
#17
Re: stl map of vectors
@laserlight: ok ..anyway i wont be doing this search over and over again ..i am trying to understand and digest all the very useful inputs given.
-
August 19th, 2015, 11:24 AM
#18
Re: stl map of vectors
Originally Posted by laserlight
In themselves, nothing, except that in this case the std::find generic algorithm expresses the intent more clearly with a name and removes the need to break out of nested loops with a goto as the simpler break would suffice.
I personally prefer structure over logic and that's why the (benign) goto in my solution doesn't bother me at all. It rather makes the code clearer to me.
But if break is so disgusting why didn't you replace the outermost loop with a function too (say find_if)? That would remove also the remaning break from your code.
Furthermore the C++ range for-loops are stateless and count as functions in my book so I don't feel any particular urge to replace them with functions for functional paradigmic reasons.
Finally many problems (like this one) can easily be executed in parallel. Then it becomes limiting to implement them using inherently sequential functions from the standard library. A solution based on range for-loops is much more readily converted into parallel (using available concurrency librares).
-
August 19th, 2015, 11:27 AM
#19
Re: stl map of vectors
Weird, did the posts go out of sync? I was fairly certain that I was replying to tiliavirga's post, but it looks like my post now appears before the post that I was responding to.
-
August 19th, 2015, 11:30 AM
#20
Re: stl map of vectors
Originally Posted by laserlight
Weird, did the posts go out of sync? I was fairly certain that I was replying to tiliavirga's post, but it looks like my post now appears before the post that I was responding to.
You must have replied to an earlier post I accidentally posted and then deleted. My reply to your post is #18. I'm not used to quick replies at this forum but I'll be more careful from now on.
Last edited by tiliavirga; August 19th, 2015 at 11:36 AM.
-
August 19th, 2015, 11:47 AM
#21
Re: stl map of vectors
Originally Posted by tiliavirga
You must have replied to an earlier post I accidentally posted and then deleted. My reply to your post is #18.
No, my post #16 is a reply to your post #18. That is why I found it strange, but yeah, "posted then deleted" does explain it. Talk about concurrency
Anyway, to address your additional points:
Originally Posted by tiliavirga
Furthermore the C++ range for-loops are stateless and count as functions in my book so I don't feel any particular urge to replace them with functions for functional paradigmic reasons.
That does not make sense to me: a range-based for loop is a loop statement, not a function. That said, I do like them precisely because I feel that they make things simpler these days such that there is less benefit in some previously useful application of generic algorithms. For example, previously if you want to say, print the elements of a vector (or more generally, a container that might not have random access by index, hence the use of iterators) to standard output, you have a choice between something pretty verbose like this:
Code:
for (std::vector<T>::iterator iter = some_vector.begin(); iter != some_vector.end(); ++iter)
{
std::cout << *iter << " ";
}
and this:
Code:
std::copy(some_vector.begin(), some_vector.end(), std::ostream_iterator<T>(std::cout, " "));
whereas now this may span more lines than the generic algorithm version and lack the descriptive element of the name, but it is arguably easier to read and understand (no need to figure out the ostream_iterator) so the lack of the algorithm name is no loss:
Code:
for (const auto& item : some_vector)
{
std::cout << item << " ";
}
Originally Posted by tiliavirga
Finally many problems (like this one) can easily be executed in parallel. Then it becomes limiting to implement them using inherently sequential functions from the standard library. A solution based on range for-loops is much more readily converted into parallel (using available concurrency librares).
Good point, but it seems to me that it would be useful to have a library of generic algorithms that can cater to this.
-
August 20th, 2015, 02:11 AM
#22
Re: stl map of vectors
Originally Posted by laserlight
Removing a break just for the sake of removing a break, without improving the readability of the code, is a misguided approach.
We are not talking about incomprehensible pieces of junk here but the same algorithm implemented slighly differently using standard C++ 11 features. All three versions have the same complexity and are equally efficient.
1. Two nested range-based for-loops with a terminating goto upon search hit.
2. As 1 but the innermost loop is replaced by std::find. The goto is replaced by a break.
3. As 2 but the outermost loop is replaced by std::find_if and the inner std::find is supplied by lambda. There is no break.
My personal favourite is #1. It is the most readable to me because this is how a two-dimensional search has been implemented since the dawn of programming. The range-based for-loop is core C++ and exceptionally terse and simple and even "functional" since it's stateless (no loop variable). Any programmer should grasp it with just a quick glance. In addition range-based for-loops are easily replaced by parallel equivalents from some existing concurrency library.
My personal runner up is #3. It's functional in the sense that all looping has been replaced by C++ standard functions. The downside is that sequentiality is permanent and to make it parallel the code has to be rewritten. On the upside there is no jumping (no goto no break). It's very readable to people like me who like the functional approach using lots of functions and lambdas.
My beef with #2 is that it's neither nor. It combines the drawbacks of #1 and #3 without achieving any of their benefits. You claim it's the most "readable" version but that's your personal view and even though your likings and dislikings may be important to you and your fan club it's not an argument in itself. So why is #2 more readable apart from that's what you think?
Last edited by tiliavirga; August 20th, 2015 at 02:41 AM.
-
August 20th, 2015, 02:27 AM
#23
Re: stl map of vectors
Originally Posted by tiliavirga
It's very readable to people who like the functional approach using lots of functions and lambdas.
That's a good point: part of readability depends on the reader's familiarity with the paradigms in use. Yet, C++ is multiparadigm, so I do not see a problem with mixing and matching, hence I disagree with your criticism of #2 as being "neither nor" as a drawback.
Originally Posted by tiliavirga
It combines the drawbacks of #1 and #3 without achieving any of their benefits. You claim it is the most "readable" version but that's your personal view only and even though it's important to you it's not an argument.
I have stated why I think it is more readable. So, it is not merely my personal view with no substantiation other than personal preference.
-
August 20th, 2015, 02:58 AM
#24
Re: stl map of vectors
I vote for #3 as it makes the intent instantaneously clear ( no need to ask yourself what's going on in the loops ) and fluent ( as long as you read it correctly )
Code:
auto sPDN = std::find_if( CPCRF::m_mPDN2RxSessionIds.begin(), CPCRF::m_mPDN2RxSessionIds.end(), [&]( auto const& keypair )
{ return std::find( keypair.second.begin(), keypair.second.end(), sSessionId ) != keypair.second.end(); } );
if( sPDN != CPCRF::m_mPDN2RxSessionIds.end() )
{
// ...
}
even better, with ( hopefully ) c++17 range support
Code:
if( auto sPDN = std::find_if( CPCRF::m_mPDN2RxSessionIds, [&]( auto const& keypair )
{ return std::find( keypair.second, sSessionId ); } ) )
{
auto foundPDN = sPDN.front().first;
// ...
}
-
August 20th, 2015, 03:04 AM
#25
Re: stl map of vectors
Originally Posted by superbonzo
even better, with ( hopefully ) c++17 range support
That looks good. Could you link to the relevant proposal?
-
August 20th, 2015, 03:28 AM
#26
Re: stl map of vectors
Originally Posted by laserlight
That's a good point: part of readability depends on the reader's familiarity with the paradigms in use. Yet, C++ is multiparadigm, so I do not see a problem with mixing and matching, hence I disagree with your criticism of #2 as being "neither nor" as a drawback.
Personally I consider the range-based for-loop and the standard functions to be well within the functional paradigm so #2 doesn't even represent a mix and match of paradigms to me.
I dislike #2 simply because it represents the worst of #1 and #3. The function in #2 cements sequentiality (which #1 doesn't) without getting rid of break (which #3 does).
I have stated why I think it is more readable. So, it is not merely my personal view with no substantiation other than personal preference.
Where please?
All I see is your personal view dressed up as tokens of high readability.
Last edited by tiliavirga; August 20th, 2015 at 04:09 AM.
-
August 20th, 2015, 03:41 AM
#27
Re: stl map of vectors
Originally Posted by laserlight
That looks good. Could you link to the relevant proposal?
there are many of them ( the code above is essentially boost.range ); I think the most advanced design to date is Niebler's range v3 but I don't think it's ready for inclusion in the std. If I had to bet, I wouldn't count on a 2017 ship date ...
after all, ranges are a major abstraction with vast interactions with the standard ( including yet to be released features like the much awaited Concept Lite ) and a lot of still unresolved issues ...
-
August 20th, 2015, 03:55 AM
#28
Re: stl map of vectors
Originally Posted by superbonzo
I vote for #3 as it makes the intent instantaneously clear ( no need to ask yourself what's going on in the loops ) and fluent ( as long as you read it correctly )
I agree but I find #1 better for reasons of familiarity and potential concurrency.
Firstly, #1 should be more comprehensible to a larger audience. Two nested loops iterating over a two-dimensional data structure is as old as the hills.
Secondly, #1 is easily modified to parallel execution using available concurrency libraries. This reduces the risk of having to rethink and rewrite the algorithm in the future.
Last edited by tiliavirga; August 20th, 2015 at 04:10 AM.
-
August 20th, 2015, 04:18 AM
#29
Re: stl map of vectors
Originally Posted by tiliavirga
I agree but I find #1 better for reasons of familiarity and potential concurrency.
Firstly, #1 should be more comprehensible to a larger audience. Two nested loops iterating over a two-dimensional data structure is as old as the hills.
in my ( personal ) experience, descriptive and truth-telling names are far more important than anything else. Moreover, I'd have serious problems working with a programmer that finds std algorithms "unfamiliar" ...
the problem with #1 is that range based for loops ( however terse ) mean "traverse something" whereas I want that code to tell me "find something", the difference is huge IMO ... especially when you review/change your code months/years later ...
Originally Posted by tiliavirga
Secondly, #1 is easily modified to parallel execution using available concurrency libraries. This reduces the risk of having to rethink and rewrite the algorithm in the future.
uhm, I'd also have serious problems working with a programmer that does not *think* ( and think and think and think ... ) when adding parallelism to some piece of code ... yes, you can easily gain orders of magnitude of run time with those libraries, but exploting your parallel hardware optimally and packing the result in a quality product looks like another story ...
Last edited by superbonzo; August 20th, 2015 at 04:20 AM.
-
August 20th, 2015, 04:19 AM
#30
Re: stl map of vectors
Originally Posted by superbonzo
there are many of them ( the code above is essentially boost.range ); I think the most advanced design to date is Niebler's range v3 but I don't think it's ready for inclusion in the std. If I had to bet, I wouldn't count on a 2017 ship date ...
I see. Thanks!
Originally Posted by superbonzo
after all, ranges are a major abstraction with vast interactions with the standard ( including yet to be released features like the much awaited Concept Lite ) and a lot of still unresolved issues ...
Yeah, I recall reading Stepanov, if I remember correctly, arguing that ranges would be superior to explicit iterator pairs, but I was unaware that such a proposal might actually be close to becoming standard.
Originally Posted by tiliavirga
Firstly, #1 should be more comprehensible to a larger audience.
I think that, correspondingly, that is a weakness with the use of generic algorithms: if you do not remember what the parameters mean, you'll have to look them up, thus negating the advantage conferred by the context supplied by the generic algorithm's name.
Originally Posted by tiliavirga
Two nested loops iterating over a two-dimensional data structure is as old as the hills.
True, but you still need to figure out why, and it is "as old as the hills" precisely because it is so common that a great many reasons are plausible. This might not be hard (and it certainly is not hard to see that a search is being done in the case that we were discussing), but a generic algorithm would immediately provide some of that information.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|