2015-08-27 45 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