I want to replace the calls to boost::lexical_cast<std::string>(d) with a solution that:
- Does not use locales (I suspect it to be the cause of slow-down in multi-threaded apps),
 - Preserves the same output as 
lexical_cast. 
I am using a generator written in Boost.Spirit.Karma (because it is faster). But after the change the results are different, because Karma has its own way of displaying fractional parts of doubles.
I know that to some extent one can control the double generator with policies, but my attempts fail. The best I can come up with is this generator customization and this test program:
#include <limits>
#include <string>
#include <iostream>
#include <boost/lexical_cast.hpp>
#include <boost/spirit/include/karma.hpp>
namespace karma = boost::spirit::karma;
template <typename Num>
struct fp_policy : karma::real_policies<Num>
{
  template <typename OutputIterator>
  static bool dot (OutputIterator& sink, Num n, unsigned /*precision*/)
  {
      if (n)
        return karma::char_inserter<>::call(sink, '.');  // generate the dot by default
      else
        return false;
  }
  static unsigned precision(Num)
  {
      return 15;
  }
};
karma::real_generator<double, fp_policy<double>> const fp_generator {};
std::string karma_to_string(double const& v)
{
    std::string ans;
    std::back_insert_iterator<std::string> sink {ans};
    (void)karma::generate(sink, fp_generator, v);
    return ans;
}
void test_number (double x)
{
  std::cout << "stream:        " << x << "\n";
  std::cout << "lexiical_cast: " << boost::lexical_cast<std::string>(x) << "\n";
  std::cout << "spirit:        " << karma_to_string(x) << "\n";
  std::cout << "--------------------------------------------" << std::endl;
}
int main()
{
  test_number(0.45359237);
  test_number(111.11);
  test_number(1.0);
  test_number(3.25);
}
And it gives the following output:
stream:        0.453592
lexiical_cast: 0.45359237000000002
spirit:        0.45359237
--------------------------------------------
stream:        111.11
lexiical_cast: 111.11
spirit:        111.109999999999999
--------------------------------------------
stream:        1
lexiical_cast: 1
spirit:        1
--------------------------------------------
stream:        3.25
lexiical_cast: 3.25
spirit:        3.25
--------------------------------------------
And as you can see there are obvious differences. If I go with the default generator for doubles (karma::double_), results still vary but in different places:
stream:        0.453592
lexiical_cast: 0.45359237000000002
spirit:        0.454
--------------------------------------------
stream:        111.11
lexiical_cast: 111.11
spirit:        111.11
--------------------------------------------
stream:        1
lexiical_cast: 1
spirit:        1.0
--------------------------------------------
stream:        3.25
lexiical_cast: 3.25
spirit:        3.25
--------------------------------------------
My question: how to configure the generator for doubles (or if it is even possible?) so that the output is closer to stream based converters?