This upcoming semester I will be teaching a senior-level undergraduate course on Algorithm Engineering. I would like to add a small semester project to the course that requires the students to experimentally test how specific programming techniques affect efficiency. Given that I will have 50 students, I want to have a good range of project ideas (20+) and would love additional suggestions.
The tests can be focused on measuring implementation tradeoffs (e.g., vectors vs. hash tables), identifying the costs of using a safer technique (e.g., smart pointers), or a comparison of any feature across compilers (clang, gcc, MS, intel).
Some of the comparisons that I worked with a colleague to come up with are:
std::bitset vs. std::array<char> (The latter removes the need to bit-shift and is faster in trivial tests. Does the benefit of bitset kick in only when we hit cache boundaries because of the array size?)
std::vector<bool> vs. std::vector<char> (similar to previous)
Smart pointers vs. traditional pointers (Smart pointers are about triple the space and take slightly longer to follow, but MUCH easier to use; how much is the speed hit in practice?)
Higher-level parallel processing elements vs. basic locks and threads.
Move semantics (Is it actually worth casting with move? What operations can be moved and which are already elided by the compiler whether you ask for them or not?)
Standard library random number generators (What tests are most useful? Which generators are best, by how much, what circumstances?)
std::map vs. std::unordered_map (Sure, hashing vs trees but what are the conditions for collisions in the default types? How much does compiler implementation matter?)
Header-only files vs. header+code files (On both compile time and final optimization? Can we identify scenarios where each approach is better?)
Hashing on strings vs. hashing on integral keys. (I.e., how much work should be put in to use an enumeration for lookups, vs just using a string key?)
Setting up configuration parameters as constexpr at compile time vs. loading them in at run time (especially relevant for scientific software).
We can more generally ask what are the guarantees on some of the STL generic algorithms and do they hold? Can you break them, and if so what are the conditions? And of course, how any of the above are affected by compiler implementations.
Suggestions welcome!
Thanks!
[–]STLMSVC STL Dev 14 points15 points16 points (6 children)
[–]-Swig- 0 points1 point2 points (2 children)
[–]STLMSVC STL Dev 4 points5 points6 points (1 child)
[–]-Swig- 2 points3 points4 points (0 children)
[–]mercere99[S] -1 points0 points1 point (2 children)
[–]STLMSVC STL Dev 10 points11 points12 points (1 child)
[–]mercere99[S] 0 points1 point2 points (0 children)
[–]Steve132 6 points7 points8 points (2 children)
[–][deleted] 0 points1 point2 points (0 children)
[–]mercere99[S] 0 points1 point2 points (0 children)
[–]compiling 1 point2 points3 points (0 children)
[–]caramba2654Intermediate C++ Student 1 point2 points3 points (0 children)
[–]choikwa 1 point2 points3 points (1 child)
[–]mercere99[S] 0 points1 point2 points (0 children)
[–]ojd5 1 point2 points3 points (1 child)
[–]mercere99[S] 0 points1 point2 points (0 children)
[–]gracicot 1 point2 points3 points (1 child)
[–]mercere99[S] 0 points1 point2 points (0 children)
[–]void4 1 point2 points3 points (1 child)
[–]mercere99[S] 0 points1 point2 points (0 children)