设计方法、字符串表数据、变量、stl内存使用

发布于 2024-08-24 13:54:14 字数 505 浏览 4 评论 0 原文

我有一个像这样的旧结构类: typedef vector> VARTYPE_T; 作为单个变量工作。该变量可以保存从列表中的一个值到表格之类的数据。对于坐标 (x,y,z),大多数值为 long、double、string 或 double [3]。我只是根据需要转换它们。变量 在这样的映射中进行管理: map 其中字符串保存变量名称。当然,他们都在课堂上。 我还有一棵节点树,其中每个节点都可以保存这些变量映射之一。

为此,我使用 VS 2008 SP1 检测到大量内存碎片。检查 stlport,stlport 似乎更快(20%)并且使用更少的内存(30%,对于我的测试用例)。

所以问题是: 通过快速正确使用内存来解决此要求的最佳实现是什么? 我应该编写一个自己的分配器,例如池分配器。你会怎么做?

预先感谢,

豪伊

I have an old structure class like this: typedef vector<vector<string>> VARTYPE_T; which works as a single variable. This variable can hold from one value over a list to data like a table. Most values are long,double, string or double [3] for coordinates (x,y,z). I just convert them as needed. The variables
are managed in a map like this : map<string,VARTYPE_T *> where the string holds the variable name. Sure, they are wrapped in classes.
Also i have a tree of nodes, where each node can hold one of these variablemaps.

Using VS 2008 SP1 for this, i detect a lot of memory fragmentation. Checking against the stlport, stlport seemed to be faster (20% ) and uses lesser memory (30%, for my test cases).

So the question is:
What is the best implementation to solve this requirement with fast an properly used memory ?
Should i write an own allocator like a pool allocator. How would you do this ?

Thanks in advance,

Howie

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

雨后彩虹 2024-08-31 13:54:14

更改 typedef 矢量<矢量<字符串>> VARTYPE_T; 到 typedef deque> VARTYPE_T; 并检查是否仍然存在内存碎片。

顺便问一下,你如何用VS 2008 SP1测量它?

更新:
我知道 HP 如何处理 HP-UX 内存碎片。经过一些搜索后,我发现了一个有趣的链接 低碎片堆。这是一段话:低碎片堆 (LFH) 有助于减少堆碎片。对我来说,这很有趣,因为它类似于 HP 处理内存碎片的方法,当然从它的描述来看。我认为(除了使用双端队列之外)尝试检查是另一个好主意。 `

更新 2:
1)速度。您之前没有谈到过速度,所以我没有任何指导来给您一些好的建议。我也不知道你的程序执行时大部分时间都花在哪里。

如果您认为它主要花费时间将字符串转换为长整型和双精度型,那么您只需执行一次此转换,并在访问变量值时使用它。不存储字符串而是存储实际值可能是个好主意。例如在联合体或 Boost.Variant 中。
如果您认为该变量缺少可以快速访问其值的索引,您应该添加这些索引。

2)内存使用情况。您是否真的正在编写一个运行数天的服务器应用程序并且应该非常关心它的内存消耗?那么我已经告诉过你,在 Windows 上使用低碎片堆并尝试使用小于 16K 的块大小。还可以消除内存泄漏。当然检查它,但据我了解低碎片堆必须处理你的消息。

3)如果您编写服务器应用程序,那么 std::vector 有时不是一个好的选择。它在一个块中分配内存。如果超过 16K,可能会导致内存碎片。

4) 最后,看看 HP-UX 中关于内存分配的一份好的报告是什么样的(以便找到内存碎片):

Actual Heap Usage:
    Heap Start  =   0x60000000000fea38
    Heap End    =   0x6000000026580000
    Heap Size   =   642258376 bytes

Outstanding Allocations:
    251948524 bytes allocated in 4239425 blocks
                              Detailed Report

-------------------------------------------------------------------------
65343264 bytes in 1361318 blocks (25.94% of all bytes allocated)
These range in size from 48 to 48 bytes and are allocated
#0  stlp_std::__malloc_alloc::allocate(unsigned long&)   from ./libstlport.so.5.1
#1  boost::multi_index::detail::ordered_index<boost::multi_index::identity<csubs::clnt_tax_hist_t>, stlp_std::less<csubs::clnt_tax_hist_t>, boost::multi_index::detail::nth_layer<1, csubs::clnt_tax_hist_t, boost::multi_index::indexed_by<boost::multi_index::ordered_non_unique<boost::multi_index::identity<csubs::clnt_tax_hist_t>, mpl_::na, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, hrs_allocator::counting_allocator<csubs::clnt_tax_hist_t, (hrs_allocator::allocator_enums)9> >, boost::mpl::vector0<mpl_::na>, boost::multi_index::detail::ordered_non_unique_tag>::insert(csubs::clnt_tax_hist_t const&)   at _alloc.h:381



-------------------------------------------------------------------------
47510512 bytes in 848402 blocks (18.86% of all bytes allocated)
These range in size from 56 to 56 bytes and are allocated
#0  stlp_std::__malloc_alloc::allocate(unsigned long&)   from ./libstlport.so.5.1
#1  csubs::cache_impl<csubs::subs_data_t, csubs::search_policy_range<false>, csubs::erase_policy_range, hrs_allocator::counting_allocator<csubs::subs_data_t, (hrs_allocator::allocator_enums)5>, boost::multi_index::multi_index_container<csubs::subs_data_t, boost::multi_index::indexed_by<boost::multi_index::ordered_non_unique<boost::multi_index::identity<csubs::subs_data_t>, mpl_::na, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, hrs_allocator::counting_allocator<csubs::subs_data_t, (hrs_allocator::allocator_enums)5> > >::put(csubs::subs_data_t const&)   at _alloc.h:381
#2  csubs::db_cache_loader<csubs::cache_impl<csubs::subs_data_t, csubs::search_policy_range<false>, csubs::erase_policy_range, hrs_allocator::counting_allocator<csubs::subs_data_t, (hrs_allocator::allocator_enums)5>, boost::multi_index::multi_index_container<csubs::subs_data_t, boost::multi_index::indexed_by<boost::multi_index::ordered_non_unique<boost::multi_index::identity<csubs::subs_data_t>, mpl_::na, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, hrs_allocator::counting_allocator<csubs::subs_data_t, (hrs_allocator::allocator_enums)5> > >, csubs::ctrl_loader_nocheck>::operation()   at cache_subs_loaders.h:121
#3  csubs::group_subs_cache::load_caches_from_db(db_date const&, csubs::cache_options const&, otl_connect&, csubs::cache_stat*)   at ./caches/cache_subs_caches.cpp:1452

等等。

Change typedef vector<vector<string>> VARTYPE_T; to typedef deque<deque<string>> VARTYPE_T; and check if there is still memory fragmentation.

By the way, how do you measure it with VS 2008 SP1 ?

Update:
I know how HP handles on HP-UX memory fragmentation. After doing some search I found an interesting link Low-fragmentation Heap. This is a quote: The low-fragmentation heap (LFH) helps to reduce heap fragmentation. To me it is interesting since it resembles the approach of HP to memory fragmentation judging of course from its description. I think (besides using deque) it is another good idea to try and check. `

Update 2:
1) Speed. You have told nothing about speed before so I don't have any guidance in order to give you some good advice. I also don't know where your program spends most of the time while executing.

If you think that it mainly spends time in converting strings to longs and doubles then you have to do this conversion only once and use it when accessing values of variables. Probably it is a good idea to store not strings but real values. For example in a union or Boost.Variant.
If you think that the variable lacks indexes that let quick access to its values you should add these indexes.

2) Memory usage. Are you actually writing a server application running for days and should care a lot about its memory consumption ? Then I already told you, use Low-fragmentation Heap on Windows and try to use block sizes fewer then 16K. Also get rid of memory leaks. Of course check it but as far as I understand Low-fragmentation Heap must handle you news.

3) If you write a server application then std::vector sometimes is not a good choice. It allocates memory in one block. If it is more than 16K this might result in memory fragmentation.

4) Finally, look how a good report from HP-UX about memory allocations looks like (in order to find memory fragmentation):

Actual Heap Usage:
    Heap Start  =   0x60000000000fea38
    Heap End    =   0x6000000026580000
    Heap Size   =   642258376 bytes

Outstanding Allocations:
    251948524 bytes allocated in 4239425 blocks
                              Detailed Report

-------------------------------------------------------------------------
65343264 bytes in 1361318 blocks (25.94% of all bytes allocated)
These range in size from 48 to 48 bytes and are allocated
#0  stlp_std::__malloc_alloc::allocate(unsigned long&)   from ./libstlport.so.5.1
#1  boost::multi_index::detail::ordered_index<boost::multi_index::identity<csubs::clnt_tax_hist_t>, stlp_std::less<csubs::clnt_tax_hist_t>, boost::multi_index::detail::nth_layer<1, csubs::clnt_tax_hist_t, boost::multi_index::indexed_by<boost::multi_index::ordered_non_unique<boost::multi_index::identity<csubs::clnt_tax_hist_t>, mpl_::na, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, hrs_allocator::counting_allocator<csubs::clnt_tax_hist_t, (hrs_allocator::allocator_enums)9> >, boost::mpl::vector0<mpl_::na>, boost::multi_index::detail::ordered_non_unique_tag>::insert(csubs::clnt_tax_hist_t const&)   at _alloc.h:381



-------------------------------------------------------------------------
47510512 bytes in 848402 blocks (18.86% of all bytes allocated)
These range in size from 56 to 56 bytes and are allocated
#0  stlp_std::__malloc_alloc::allocate(unsigned long&)   from ./libstlport.so.5.1
#1  csubs::cache_impl<csubs::subs_data_t, csubs::search_policy_range<false>, csubs::erase_policy_range, hrs_allocator::counting_allocator<csubs::subs_data_t, (hrs_allocator::allocator_enums)5>, boost::multi_index::multi_index_container<csubs::subs_data_t, boost::multi_index::indexed_by<boost::multi_index::ordered_non_unique<boost::multi_index::identity<csubs::subs_data_t>, mpl_::na, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, hrs_allocator::counting_allocator<csubs::subs_data_t, (hrs_allocator::allocator_enums)5> > >::put(csubs::subs_data_t const&)   at _alloc.h:381
#2  csubs::db_cache_loader<csubs::cache_impl<csubs::subs_data_t, csubs::search_policy_range<false>, csubs::erase_policy_range, hrs_allocator::counting_allocator<csubs::subs_data_t, (hrs_allocator::allocator_enums)5>, boost::multi_index::multi_index_container<csubs::subs_data_t, boost::multi_index::indexed_by<boost::multi_index::ordered_non_unique<boost::multi_index::identity<csubs::subs_data_t>, mpl_::na, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, hrs_allocator::counting_allocator<csubs::subs_data_t, (hrs_allocator::allocator_enums)5> > >, csubs::ctrl_loader_nocheck>::operation()   at cache_subs_loaders.h:121
#3  csubs::group_subs_cache::load_caches_from_db(db_date const&, csubs::cache_options const&, otl_connect&, csubs::cache_stat*)   at ./caches/cache_subs_caches.cpp:1452

and so on.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文