簡體   English   中英

如何將我的Libsvm矢量加速到std :: vector <float> 轉換?

[英]How to speedup my Libsvm vector to std::vector<float> conversion?

介紹

我有一個形式的libsvm向量:

{I_1:V_1; I_2:V_2; ...; 1-N:v_n}

其中i_j:v_j分別表示索引 如果該值為null,則不會給出任何索引。

我的目標是計算兩個libsvm向量之間的歐式距離。 為此,我必須將它們轉換為相同大小的vector<float> 在下面的示例中,我將顯示用於將libsvm矢量轉換為vector<float>的函數。


第一列的索引為2648 ,值= 0.408734,表示該列之前的所有值均為零。

LIBSVM矢量= 2648:0.408734; 4157:0.609588; 6087:0.593104; 26747:0.331008


源代碼

#include <vector>
#include <string>
#include <chrono>
#include <boost/algorithm/string.hpp>

using namespace std;
using namespace chrono;
//convert libsvm vector to float vector in order to compute the similarity
vector<float> splitVector(const vector<string> &);

int main()
{
   vector<string> libsvm {"2648:0.408734","4157:0.609588","6087:0.593104","26747:0.331008" };
   high_resolution_clock::time_point t1 = high_resolution_clock::now();
   vector<float> newVec = splitVector(libsvm);
   high_resolution_clock::time_point t2 = high_resolution_clock::now();
   auto duration = chrono::duration_cast<chrono::microseconds>( t2 - t1 ).count();
   cout <<"construction time: " << duration << endl;
   return 0;
}

vector<float> splitVector(const vector<string> & v)
{
    int numberofterms = 266373;
    vector<float> values;
    vector<int> previous_idx;
    for(int i = 0; i < v.size(); i++)
    {
        vector<string> tmpv;
        boost::split(tmpv, v[i] , boost::is_any_of(":"));
        //idx:value
        int idx = atoi(tmpv[0].c_str());
        float val = atof(tmpv[1].c_str());

        //summation of previous indices
        int sum = accumulate(previous_idx.begin(), previous_idx.end(), 0);
        int n = idx - (sum + i + 1);
        //fill vector with 0s
        for(int k = 0; k < n; k++)
            values.push_back(0.0);
        //add value
        values.push_back(val);
        previous_idx.push_back(n);
    }//end for

    int paddingsize = numberofterms - values.size();

    for(int i = 0; i < paddingsize;i++)
    {
      values.push_back(0.0);
    }
    return values;
}//end function

問題

轉換時間大約為0,00866秒,當我有大約1000個向量時,它變慢了。 有沒有更快的方法可以將libsvm向量轉換為vector<float>


修改功能

values.resize(266373,0.0);
void splitVector(const vector<string> & v, vector<float> & values)
{
    vector<string> tmpv;
    for(int i = 0; i < v.size(); i++)
    {
        boost::split(tmpv, v[i] , boost::is_any_of(":"));
        //idx:value
        int idx = atoi(tmpv[0].c_str());
        float val = atof(tmpv[1].c_str());
        tmpv.clear();
        values[idx] = val;
    }//end for

}//end function

您可以通過重用vector來減少內存分配的時間成本。 更加具體,

  • 通過在for循環之前聲明tmpv來重用tmpv ,並在每個循環的開始處調用tmpv.clear()
  • 通過values.reserve()預先分配values 並通過values.resize(266373, 0.0)填充它values.resize(266373, 0.0)而不是重復push_back()
  • 如果可能,請重用previous_idx 這可能會對代碼結構和可維護性產生負面影響。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM