2015-08-27 86 views
0

我調用了一個庫函數,該函數接受指向std::set的指針並處理它的元素。獲取std :: set子集的有效方法

但是,它只處理一定數量的元素(比方說100),如果該集合有更多的元素,它只會引發異常。不過,我收到了一套更大的尺寸。所以我需要有效的方法來獲得std::set的子集。

目前,我將100個元素複製到臨時集並將其傳遞給該函數。

struct MyClass 
{ 
    // Class having considerably large size instance 
}; 

// Library function that processes set having only 100 elements at a time 
void ProcessSet (std::set<MyClass>* ptrMyClassObjectsSet); 

void FunctionToProcessLargeSet (std::set<MyClass>& MyClassObjSet) 
{ 
    std::set<MyClass> MyClass100ObjSet; 

    // Cannot pass MyClassObject as it is to ProcessSet as it might have large number of elements 
    // So create set of 100 elements and pass it to the function 
    std::set<MyClass>::iterator it; 
    for (it = MyClassObjSet.begin(); it != MyClassObjSet.end(); ++it) 
    { 
     MyClass100ObjSet.insert (*it); 

     if (MyClass100ObjSet.size() == 100) 
     { 
      ProcessSet (&MyClass100ObjSet); 
      MyClass100ObjSet.clear(); 
     } 
    } 

    // Prrocess remaining elments 
    ProcessSet (&MyClass100ObjSet); 
    MyClass100ObjSet.clear(); 
} 

但它影響性能。任何人都可以建議更好的方法來做到這一點?

+2

你可以展示你目前在做什麼的[mcve]? – NathanOliver

+0

如果庫需要一系列小的'std :: set'對象,那麼這就是你必須創建的。事實上,他們是其他東西的子集似乎沒有幫助。圖書館是否提供其他選擇?他們是堆分配的對象,如「std :: string」? – Potatoswatter

+0

@Patatoswatter:對象是堆分配。我在想如果它是數組,我會通過指定數組索引來傳遞「原始數組的子部分」,但在std :: set的情況下我不能這樣做(或者有什麼辦法可以做到這一點?) – Atul

回答

1

由於它看起來像被鎖定在必須使用子集。我調整了一下你的代碼,我認爲它可能會更快。它仍然是O(n)操作,但for循環中沒有分支,這應該會提高性能。

void FunctionToProcessLargeSet(std::set<MyClass>& MyClassObjSet) 
{ 
    int iteration = MyClassOgjSet.size()/100; // get number of times we have collection of 100 
    auto it = MyClassObjSet.begin(); 
    auto end = MyClassObjSet.begin(); 
    for (; iteration == 0; --iteration) 
    { 
     std::advance(end, 100); // move end 100 away 
     std::set<MyClass> MyClass100ObjSet(it, std::advance(it, end)); // construct with iterator range 
     std::advance(it, 100); // advace it to end pos 
     ProcessSet(&MyClass100ObjSet); // process subset 
    } 
    if (MyClassOgjSet.size() % 100 != 0) // get last subset 
    { 
     std::set<MyClass> MyClass100ObjSet(it, MyClassObjSet.end()); 
     // Prrocess remaining elments 
     ProcessSet(&MyClass100ObjSet); 
    } 
} 

讓我知道如果這對你來說運行得更快。

1

嗯,這聽起來像一個壞的庫設計,但如果你有,你有什麼,然後上班:

  • 如果庫可以接受一對迭代器 - 這是最簡單的方式使用去std::advance
  • 如果它的模板,並可以接受std::set<T>,然後複製您所設定的一部分std::set<std::reference_wrapper<T>>可能會表現得更好,如果照搬T是緩慢的(見here看有沒有副本創建)
  • 如果只接受std::set<ParticularObjectType>,我沒有看到複製數據的方法。

希望這有助於

羅斯季斯拉夫。

+0

非常感謝!我會評估這些選項。 – Atul