Skip to main content
added 66 characters in body; edited title
Source Link
Simon Forsberg
  • 59.7k
  • 9
  • 157
  • 311

Reducing amount of allocations in a program Program that handles program options

I'm using boost::program_options to parse input from the user. However, while the standard library makes this an easy task to do, it's causing an (in my opinion) excessive amount of allocations. Of course, for such a small program on modern systems, it probably isn't that big of a deal, but I would like to nip the problem in the bud before it spirals out of control.

How can I reduce the number of allocations in this program?

Here's an example of what valgrind reports:

Reducing amount of allocations in a program that handles program options

I'm using boost::program_options to parse input from the user. However, while the standard library makes this an easy task to do, it's causing an (in my opinion) excessive amount of allocations. Of course, for such a small program on modern systems, it probably isn't that big of a deal, but I would like to nip the problem in the bud before it spirals out of control. Here's an example of what valgrind reports:

Program that handles program options

I'm using boost::program_options to parse input from the user. However, while the standard library makes this an easy task to do, it's causing an (in my opinion) excessive amount of allocations. Of course, for such a small program on modern systems, it probably isn't that big of a deal, but I would like to nip the problem in the bud before it spirals out of control.

How can I reduce the number of allocations in this program?

Here's an example of what valgrind reports:

Source Link

Reducing amount of allocations in a program that handles program options

I'm using boost::program_options to parse input from the user. However, while the standard library makes this an easy task to do, it's causing an (in my opinion) excessive amount of allocations. Of course, for such a small program on modern systems, it probably isn't that big of a deal, but I would like to nip the problem in the bud before it spirals out of control. Here's an example of what valgrind reports:

 $ test
Compression level was not set.
 $ test --help
Allowed options:
  --help                produce help message
  --compression arg     set compression level

 $ test --compression 10
Compression level was set to 10.
 $ test --compression 5
Compression level was set to 5.
 $ test --compressio  

error: the required argument for option '--compression' is missing
total heap usage: 266 allocs, 266 frees, 11,430 bytes allocated

And the code dump:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
#include <memory>
#include <sstream>

#include <cstring>

#include <boost/program_options.hpp>
#include <boost/iterator/transform_iterator.hpp>
namespace po = boost::program_options;

// "std::vector<std::string> to char* array"
// http://stackoverflow.com/a/7048972/3920237
const char *convert_to_cstr(const std::string & s)
{
   return s.c_str(); 
}

int main(int argc, char* argv[])
{
    po::options_description desc("Allowed options");
    desc.add_options()
        ("help", "produce help message")
        ("compression", po::value<int>(), "set compression level")
    ;
    
    std::string input = "";

    const std::string prompt = " $ ";

    std::vector<std::string> args;
    std::istringstream iss;
    
    std::string token;
    
    po::variables_map vm; 
    while (true)
    {
        try {
            std::cout << prompt;
            std::getline(std::cin, input);
            if (input == "quit")
                break;
                
            iss.clear();
            iss.str(input);
            
            args.clear();
            while (iss >> token)
            {
                args.push_back(token);  
            }
            
            auto beg = boost::make_transform_iterator(args.begin(), 
                convert_to_cstr);
            auto end = boost::make_transform_iterator(args.end(), 
                convert_to_cstr);
            
            const std::vector<const char*> vc { beg, end };

            /* std::transform(args.begin(), args.end(), std::back_inserter(vc), convert); */
            vm.clear();
            po::store(po::parse_command_line(vc.size(), vc.data(), desc), vm);
            po::notify(vm);    

            if (vm.count("help")) {
                std::cout << desc << "\n";
                continue;
            }

            if (vm.count("compression")) {
                std::cout << "Compression level was set to " 
                     << vm["compression"].as<int>() << ".\n";
            } else {
                std::cout << "Compression level was not set.\n";
            }
        }
        catch(std::exception& e) {
            std::cerr << "error: " << e.what() << "\n";
            continue;
        }
        catch(...) {
            std::cerr << "Exception of unknown type!\n";
        } 
    }
    
    return 0;   
}