C++:查找程序中最大的容器
c++: Find largest container in a program
我正在尝试分析一个大型C++程序。该程序大量使用 STL 容器数据结构,如集合、映射、无序集合、无序映射、向量等。有时它们是嵌套的,例如集合映射。
我想找出,在程序的特定运行中,哪些容器包含最多的元素(即size((的最大值(。我可以对程序进行小的编辑。
如果有一种方法可以遍历所有容器,或者有一种方法可以拦截容器的(大小修改(API,这可能会有所帮助。但这些是不可能的。
你会如何处理这个问题?
补充:Linux中的平台,编译器是g++或clang++。
如果您可以进行较小的编辑,您可以将每个容器添加到它们的大列表中吗?
喜欢这个:
std::set<......> my_set; // existing code
all_containers.add( &my_set ); // minor edit IMHO
然后,您可以调用all_containers.analyse()
,该将调用每个size()
并打印结果。
你可以使用这样的东西:
struct ContainerStatsI {
virtual int getSize() = 0;
};
template<class T> struct ContainerStats : ContainerStatsI {
T* p_;
ContainerStats( T* p ) : p_(p) {}
int getSize() { return p->size(); }
};
struct ContainerStatsList {
std::list<ContainerStatsI*> list_; // or some other container....
template<class T> void add( T* p ) {
list_.push_back( new ContainerStats<T>(p) );
}
// you should probably add a remove(T* p) as well
void analyse() {
for( ContainerStatsI* p : list_ ) {
p->getSize(); // do something with what's returned here
}
}
};
当您的项目非常大并且具有大量不同容器的实例时,此方法很有用。该方法的优点是不需要修改大量代码。 它允许您缩小要查找的容器类型。此方法有助于诊断每个条件和每个类型的位置。
可以重新定义template< class T > struct allocator
.可以在 std 标头中重命名原始分配器或对其进行修改。可以对分配和取消分配进行统计。您将知道每种类型的元素的数量和大小。但是您无法知道具有元素的容器的哪个实例。
模板template< class T > struct allocator
放置在库头文件中。它始终存在,不需要重建您的开发环境库,因为据您所知,模板不可能编译成静态库(不包括专用化(。始终使用您的源编译的模板。但预编译标头可能有问题。对于项目,可以重新生成或不使用它,但对于库,则需要检查。这可能是方法的瓶颈,但验证是否存在问题很简单。
有一种经验方法不能保证准确性。当应用程序关闭时,容器会在解除分配其元素后解除分配。因此,您可以为每个父类型的容器编写统计信息,该容器类型有多少内部元素。
例如,让我们有:
vector<A>({1,2,3}) and map<string,B>({1,2}) and map<string,B>({1,2})
这将生成如下所示的释放事件列表:
B, B, map<string,B>,
A, A, map<string,A>,
A, A, A, vector<A>,
所以你可以知道 3 个元素在vector<A>
A
,2 个元素A
map<string,A>
,2 个元素A
在map<string,A>
将统计信息代码添加到 std 头文件中容器的析构函数中。这也不需要修改大项目的大量代码。但这也只显示容器类型(请参阅我的另一个答案 这里(.方法不需要 C++0x 或 C++11 或更多。
第一步也是强制性步骤是在源代码管理(例如 git(下添加您的 std 库,以便快速查看实际更改的内容以及在修改版本和原始版本之间快速切换。
将Stat
类的声明放入 std 库源文件夹中:
class Stat {
std::map<std::string,int> total;
std::map<std::string,int> maximum;
public:
template<class T>
int log( std::string cont, size_t size ) {
std::string key = cont + ": " + typeid(T).name();
if( maximum[key] < size ) maximum[key] = size;
total[key] += size;
}
void show_result() {
std::cout << "container type total maximum" << std::endl;
std::map<std::string,int>::const_iterator it;
for( it = total.begin(); it != total.end(); ++it ) {
std::cout << it->first << " " << it->second
<< " " << maximum[it->first] << std::endl;
}
}
static Stat& instance();
~Stat(){ show_result(); }
};
在项目 cpp 文件中实例化Stat
类的单例实例:
Stat& Stat::instance() {
static Stat stat;
return stat;
}
编辑标准库容器模板。在析构函数中添加统计记录。
// modify this standart template library sources:
template< T, Allocator = std::allocator<T> > vector {
...
virtual ~vector() {
Stat::instance().log<value_type>( "std::vector", this->size() );
}
};
template< Key, T, Compare = std::less<Key>,
Allocator = std::allocator<std::pair<const Key, T> > map {
...
virtual ~map(){
Stat::instance().log<value_type>( "std::map", this->size() );
}
};
例如,现在考虑一个程序:
int main() {
{
// reject to use C++0x, project does not need such dependency
std_vector<int> v1; for(int i=0;i<10;++i) v1.push_back( i );
std_vector<int> v2; for(int i=0;i<10;++i) v2.push_back( i );
std_map<int,std::string> m1; for(int i=0;i<10;++i) m1[i]="";
std_map<int,std::string> m2; for(int i=0;i<20;++i) m2[i]="";
}
Stat::instance().show_result();
return 0;
}
gcc 的结果是:
container type total maximum std::map: St4pairIiSsE 30 20 std::vector: i 20 10
如果您需要更详细的类型描述,而不是查找有关开发环境的信息。这里描述了 gcc 的这种转换:https://lists.gnu.org/archive/html/help-gplusplus/2009-02/msg00006.html
输出可能是这样的:
container type total maximum std::map: std::pair<int, std::string> 30 20 std::vector: int 20 10
- 模板元程序查找相似的连续类型名称
- 试图创建一个多线程程序来查找0-100000000之间的总素数
- 程序以使用 C++ 中的 while 循环查找一组数字的最小值
- 为什么使用数组元素查找最大数字的程序不起作用?
- 可视化 使用 VS Code 查找C++应用程序中的内存泄漏
- 程序 查找数字的重复
- 尝试创建一个程序来查找非二叉树的高度.最终得到一个很长的循环,没有答案
- 如何制作一个查找数字平方值的 c++ 程序
- std::使用迭代器映射查找距离,程序不会终止
- C++程序来查找输入数字的最小/最大值
- 需要一些帮助来查找我的程序中的逻辑错误
- 创建程序以从给定的.txt文件中查找文本,替换并计算单词
- 程序以查找给定字符串中回文的子字符串的数量
- CPP 程序二查找两个给定日期之间的天数,conol CMD
- 查找 tracee 的会合结构(正在调试的程序)
- 通过LLVM查找C / C ++程序中所有可能的路径
- 当尝试查找'*'程序在 C++ 中查找'.'
- C++:查找程序中最大的容器
- 如何查找程序正在等待的位置
- 错误:nth_element-没有重载函数实例(中位数查找程序)