CComSafeArray для разделенных табуляцией значений Предложения по улучшению скорости - PullRequest
0 голосов
/ 31 марта 2019

У меня есть необходимость конвертировать 2D CComSafe Array в текстовый поток значений, разделенных табуляцией.Массив может содержать произвольное количество значений, возможно, в миллионах.

Соответствующие фрагменты кода приведены ниже.

Я сильно подозреваю, что функция generate_response_from_data - это просто отвратительный способ генерациивыход.Но я не нашел конкретного примера лучшего способа.И да, я искал в меру своих возможностей.

Я пытался выяснить, будет ли Boost Karma лучшим решением, но, честно говоря, я просто не мог понять, как применить его для своего использования.case.

Может ли кто-нибудь предоставить информацию о более быстром методе?

// This is a 2D CComSafeArray
template<typename T>
class MyDataArray : public CComSafeArray<T>
{
public:
    MyDataArray() : CComSafeArray<T>() {}

    const T* get_value_ptr(long row, long col) const // 0-based indices.
    {
        // To shave off a tiny bit of time, validity of m_psa, row, and col are assumed.
        // Not great but for our application, those are checked prior to call.
        return &static_cast<T*>(this->m_psa->pvData)[this->m_psa->rgsabound[1].cElements * col + row];
    }

    // Other stuff for this class.
};

inline std::string my_variant_to_string(const VARIANT* p_var)
{
    // Will only ever have VT_I4, VT_R8, VT_BSTR
    if (VT_I4 == p_var->vt)
        return boost::lexical_cast<std::string>(p_var->intVal); // Boost faster than other methods!!!

    if (VT_R8 == p_var->vt)
        return boost::lexical_cast<std::string>(p_var->dblVal); // Boost faster than other methods!!!

    if (VT_BSTR == p_var->vt)
    {
        std::wstring wstr(p_var->bstrVal, SysStringLen(p_var->bstrVal));
        return Utils::from_wide(wstr); // from_wide is a conversion function I created.
    }

    //if (VT_EMPTY == == p_var->vt) {} // Technically not needed.

    return "";
}

template<typename T>
bool generate_response_from_data(const MyDataArray<T>& data_array, std::stringstream& response_body)
{
    if (2 != data_array.GetDimensions())
        return false;

    long row_begin = data_array.GetLowerBound(0);
    long row_end = data_array.GetUpperBound(0);
    long col_begin = data_array.GetLowerBound(1);
    long col_end = data_array.GetUpperBound(1);

    if (row_end < row_begin || col_end < col_begin)
        return false;

    for (long r = row_begin; r <= row_end; ++r)
    {
        for (long c = col_begin; c <= col_end; ++c)
        {
            if (c > 0)
                response_body << '\t';

            response_body << my_variant_to_string(data_array.get_value_ptr(r, c));
        }
        response_body << '\n';
    }

    return true;
}

1 Ответ

0 голосов
/ 02 апреля 2019

Спасибо @MichaelGunter.Ваше предложение перегрузить << приводит к увеличению скорости на ~ 60%!Я конвертирую из wstring для каждого значения, потому что процентное соотношение строковых значений довольно мало (если оно вообще есть) по сравнению с числовыми значениями, и преобразование всего потока в большинстве случаев может быть бесполезным. </p>

EDITED для отражения прямогопреобразование из BSTR в std :: string с помощью пользовательской функции.

std::stringstream& operator<<(std::stringstream& s, const VARIANT* p_v)
{
    if (VT_I4 == p_v->vt)
        s << p_v->intVal;
    else if (VT_R8 == p_v->vt)
        s << p_v->dblVal;
    else if (VT_BSTR == p_v->vt)
    {
        //std::wstring wstr(p_v->bstrVal, SysStringLen(p_v->bstrVal));
        s << Utils::from_bstr(p_v->bstrVal);
    }
    return s;
}

...
response_body << odata_array.get_value_ptr(r, c);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...