4
\$\begingroup\$

We have a StreamBuffer class which is not inherited from std::ios_base (or some of it's derivatives such as std::ostream) so that I can use std::fixed operations and I am trying to prevent number showing up in scientific notations. With my below code some numbers are getting shown in scientific notations. We want to avoid doing any allocations so that's why we implemented StreamBuffer class because of performance reason.

T value = 0;

template<typename U> void process(U& buf, DataOption holder) const {
    if (holder == DataOption::TYPES) {
        switch (type_) {
        case teck::PROC_FLOAT:
            buf << "{\"float\":" << value << "}";
            break;
        case teck::PROC_DOUBLE:
            buf << "{\"double\":" << value << "}";
            break;
        default:
            buf << "{\"" << type_ << "\":" << value << "}";
        }
    }
}

This is the way it is being called:

void HolderProcess::dump(std::ostream& os, DataOption holder) const 
{
    process<std::ostream>(os, holder);
}

void HolderProcess::dump(StreamBuffer& buffer, DataOption holder) const
{
    process<StreamBuffer>(buffer, holder);
}

I came up with this solution to avoid number (here value is coming in exponent form and I want to have a fixed number for that value) getting converted to scientific notation, but it uses string and it will do some allocations, which is not performance-efficient.

template <typename T> string str(T number)
{
   std::ostringstream ss;
   ss << std::fixed << number;
   return ss.str();
}

And then I can call above template method from my above each case block. This, however, will most certainly allocate more memory. Is there any better way to solve this problem which is optimized, efficient and doesn't do any allocations?

\$\endgroup\$
1
  • \$\begingroup\$ Doesn't this work? process<std::ostream>(os << std::fixed, holder); \$\endgroup\$
    – GeniusIsme
    Commented Feb 16, 2016 at 14:09

1 Answer 1

1
\$\begingroup\$

You could use vsnprintf if it's available on your system. It might seem like a step backwards to use a C-style printf derivative in C++ code, but that's what's used in gcc on my Linux machine. You can use alloca which allocates space on the stack, or a fixed size (but guaranteed sufficient) local array.

Because your StreamBuffer is not derived from std::ios_base and you haven't provided details of its implementation, I can't really show a code example but I presume that the StreamBuffer& operator<<() either is already or can be adapted to use vsnprintf.

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.