获取 std::set 子集的有效方法
Efficient way to get subset of 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();
}
但这会影响性能。谁能建议更好的方法来做到这一点?
嗯,这听起来像是一个糟糕的库设计,但如果你必须使用现有的东西,那么:
- 如果库 可以 接受一对迭代器 - 这是使用
std::advance
的简单方法
- 如果它是模板化的并且可以接受
std::set<T>
,那么如果复制 T 很慢,将你的集合的一部分复制到 std::set<std::reference_wrapper<T>>
可能会执行得更好(参见 here 以了解没有复制已创建)
- 如果它只接受
std::set<ParticularObjectType>
,我看不到复制数据的方法。
希望这对您有所帮助,
罗斯蒂斯拉夫。
因为看起来您不得不使用一个子集。我稍微调整了您的代码,我认为它对您来说可能更快。它仍然是一个 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);
}
}
如果这对你来说运行得更快,请告诉我。
我调用了一个库函数,它接受指向 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();
}
但这会影响性能。谁能建议更好的方法来做到这一点?
嗯,这听起来像是一个糟糕的库设计,但如果你必须使用现有的东西,那么:
- 如果库 可以 接受一对迭代器 - 这是使用
std::advance
的简单方法
- 如果它是模板化的并且可以接受
std::set<T>
,那么如果复制 T 很慢,将你的集合的一部分复制到std::set<std::reference_wrapper<T>>
可能会执行得更好(参见 here 以了解没有复制已创建) - 如果它只接受
std::set<ParticularObjectType>
,我看不到复制数据的方法。
希望这对您有所帮助,
罗斯蒂斯拉夫。
因为看起来您不得不使用一个子集。我稍微调整了您的代码,我认为它对您来说可能更快。它仍然是一个 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);
}
}
如果这对你来说运行得更快,请告诉我。