终于有了间茅草棚

——我走时,会否有随风飘散的痕迹?

外面的风好大,雨也淅淅沥沥的。

世间种种的诱惑不惊不扰我清梦,山高路远不绝我追踪你绝美的笑容,登高一呼时才懂始终在为你心痛,俯首对花影摇动都是东风在捉弄

世间种种的迷惑都是因你而猜错,水光月光又交融描述这朗朗的夜空,生死到头的相从似狂花落叶般从容,当一切泯灭如梦就在远山被绝
随笔 - 40, 文章 - 2, 评论 - 257, 引用 - 3

导航

<2008年12月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

留言簿(11)

随笔档案

文章档案

收藏夹

其它的我

友情连接

网页连接

搜索

最新评论

  • 1. re: 关于质数(素数)的算法
  • 1121=19*59
  • --李圆欢
  • 2. re: void *几用
  • 方法都不错
  • --员工生日礼物
  • 3. re: void *几用
  • to oshj:
    最近才悟道这个用法,没想到你都用了很多了。

    to brent:
    不是为了玩才玩,这里每种用法在特定的情况下,都有他相应的好处。不过,我是做为自己记录的,指不定什么时候就忘记了,还可以这么用。
    1. 可以使得头文件简单,而且出于实现保密的需要,还是很有用处的。
    2. 很多时候对象本身应该简洁,但往往应对不同的需要,通常需要数据对应。举个例子,比如玩家在哪个房间,在哪个房间最好不要直接记在玩家身上,用数据注入的方式,能够很快的获得该信息。
    3. 因为是做为库暴露头文件的,使用者并不关心void *的实际意义,而且能够加快编译速度。真正要关心时,就Graphics.h这个头文件是不够的,通常会需要了解整底层个实现,才能较好的扩充。
  • --清风雨
  • 4. re: void *几用
  • 还在玩C++语言,你这玩法, 又不是用在导弹导航上...
    别人看不懂的代码,都不是好代码,分数为0

    int sub(any) { any; return TRUE;}
    (void)sub(any);

  • --brent
  • 5. re: void *几用
  • 个人用3 的情况比较多
  • --oshj
  • 6. re: 简要记录sizeof和内存对齐
  • 很清楚,受教了
  • --rdeam
  • 7. re: 局部变量
  • 我不用ATL,一般都是用标准c++支持的和平台API。
    crt里的wcs和mbs转换的函数,ms的实现是不完整的,在它的实现代码里有一段说明;而且还要设置local,比较烦琐。
  • --清风雨
  • 8. re: 简单字符串转换
  • win下,atl中有CT2CA, CW2CA等一系列转换类。
    crt中有wcstombs和mbstowcs
  • --局部变量
  • 9. re: 一个奇怪但可能有用的缓存
  • vc资料站:http://www.vcmsdn.com/     对学习很有帮助的,可以上去

    看看,或加群46138350,里面有高手可以请教的。
  • --maggie
  • 10. #progma整理
  • #pragma整理
  • --hi_wyl
  • 11. re: hpho
  • 缓冲在一等程度上是临时性的,而且实际上如果保持std::vector的iterator下次使用,也会有问题。

    所以,这个问题也就是使用时不允许这样用。
  • --清风雨
  • 12. re: 一个奇怪但可能有用的缓存
  • 如果有指针引用着arrange()所调整的那块内存,那就乱了.
  • --hpho
  • 13. re: 一个奇怪但可能有用的缓存
  • 用std::string不就行了?
  • --金庆
  • 14. re: ZiDing
  • 鉴于你的建议,前段时间我看了下boost的内存对象池,没有过于深入,
    判断下来属于做法类似,性能应该相当,甚至可能我这个略好一点。

    因为编写测试是一件相当麻烦,而且要求也很高的事,而要全面又很难。

    boost的代码我看起来比较难读,维护、调试起来对我来说是一个大麻烦。所以,我一般不选择boost。
  • --清风雨
  • 15. re: 简单内存对象池
  • 和boost的对比过没有?
  • --ZiDing

阅读排行榜

评论排行榜

简单内存对象池

很久没有写blog了,一直很懒惰。这几天写了个内存对象池,用于对需要频繁的分配、释放做优化。
在windows和linux下分别试验,结果linux下只有6倍的提升(原因是linux系统内核对小对象本身就有内存对象池优化)。
测试中还发现原来stlPort的vector居然和标准有所出入,msvc8的stl倒是表现很准确(不过,ms的basic_ifstream似乎有问题)。
/**
 * 以下代码由张家旺编写完成于2007-3-29,借用请保留该声明。
 */
#ifdef _MSC_VER
# pragma once
#endif
#ifndef __MEM_POOL__
#define __MEM_POOL__
namespace useful
{

template < class T > class allocator
{
public:
 typedef size_t     size_type;
 typedef ptrdiff_t    difference_type;
 typedef T      *pointer;
 typedef const T     *const_pointer;
 typedef T      &reference;
 typedef const T     &const_reference;
 typedef T      value_type;
 pointer address( reference x ) const
 {
  return &x;
 }
 const_pointer address( const_reference x ) const
 {
  return &x;
 }
 void construct( pointer p,const T &t )
 {
  new ( p ) T( t );
 }
 void destroy( pointer p )
 {
  p->~T();
 }

 pointer allocate( size_type n = 1,void *hint = 0 );
 void deallocate( pointer p,size_type n = 1 );
 pointer constructEx( const T &t )
 {
  pointer p = allocate( 1,0 );
  new ( p ) T( t );
  return p;
 }
 void destroyEx( pointer p )
 {
  p->~T();
  deallocate( p,1 );
 }
};
template < class T1, class T2 >
 bool operator==( const allocator< T1 > &a1,const allocator< T2 > &a2 ) throw()
{
 return &a1 == &a2;
}
template < class T1, class T2 >
 bool operator!=( const allocator< T1 > &a1,const allocator< T2 > &a2 ) throw()
{
 return &a1 != &a2;
}
template < class T,int N >
class allocator1 : public allocator< T >
{
public:
 typedef size_t     size_type;
 typedef ptrdiff_t    difference_type;
 typedef T      *pointer;
 typedef const T     *const_pointer;
 typedef T      &reference;
 typedef const T     &const_reference;
 typedef T      value_type;
 template < class U > struct rebind { typedef allocator1< U,N > other; };
 allocator1( void ) throw();
 template < class U > allocator1( const allocator1< U,N > & ) throw() {}
 ~allocator1( void ) throw();
 size_type max_size( void ) const throw();
 pointer allocate( size_type n = 1,void *hint = 0 );
 void deallocate( pointer p,size_type n = 1 );
private:
 struct mem_node {
  char buf[sizeof(T)*N];
  void *use[N];
  size_type reuse;
  struct mem_node *next;
 } m_head;
 static void initialize( struct mem_node &node );
 static void finalize( struct mem_node &node );
 static void *allocate( struct mem_node &node );
 static bool deallocate( void *p,struct mem_node &node );
};
template < class T,int N >
void allocator1< T,N >::initialize( struct mem_node &node )
{
 for( size_type i = 0; i < N; ++i )
  node.use[i] = node.buf+sizeof(T)*i;
 node.reuse = N;
 node.next = 0;
}
template < class T,int N >
allocator1< T,N >::allocator1( void ) throw()
{
 initialize( m_head );
}
template < class T,int N >
void allocator1< T,N >::finalize( struct mem_node &node )
{
 if( node.next != 0 ) finalize( *node.next );
 delete &node;
}
template < class T,int N >
allocator1< T,N >::~allocator1( void ) throw()
{
 if( m_head.next != 0 ) finalize( *m_head.next );
}
template < class T,int N >
typename allocator1< T,N >::size_type
allocator1< T,N >::max_size( void ) const throw()
{
 const struct mem_node *node = &m_head;
 while( node != 0 && node->reuse < = 0 ) node = node->next;
 return node == 0 ? N : node->reuse;
}
template < class T,int N >
void *allocator1< T,N >::allocate( struct mem_node &node )
{
 return node.reuse > 0 ? node.use[--node.reuse] : 0;
}
template < class T,int N >
typename allocator1< T,N >::pointer
allocator1< T,N >::allocate( size_type,void *hint )
{
 void *p;
 struct mem_node *node = &m_head;
 while( (p=allocate(*node)) == 0 )
 {
  if( node->next != 0 ) node = node->next;
  else
  {
   struct mem_node *node_ = new struct mem_node;
   initialize( *node_ );
   node = node->next = node_;
  }
 }
 return static_cast< pointer >( p );
}
template < class T,int N >
bool allocator1< T,N >::deallocate( void *p,struct mem_node &node )
{
 if( p < node.buf || p >= node.use ) return false;
 node.use[node.reuse++] = p;
 return true;
}
template < class T,int N >
void allocator1< T,N >::deallocate( pointer p,size_type n )
{
 struct mem_node *node = &m_head,*prev;
 while( !deallocate(p,*node) ) prev = node,node = node->next;
 if( node != &m_head && node->reuse >= N )
 {
  prev->next = node->next;
  delete node;
 }
}
template < class T >
class allocator2 : public allocator< T >
{
public:
 typedef size_t     size_type;
 typedef ptrdiff_t    difference_type;
 typedef T      *pointer;
 typedef const T     *const_pointer;
 typedef T      &reference;
 typedef const T     &const_reference;
 typedef T      value_type;
 template < class U > struct rebind { typedef allocator2< U > other; };
 allocator2( size_type num = 1024 ) throw();
 template < class U > allocator2( const allocator2< U > & ) throw() {}
 ~allocator2( void ) throw();
 size_type max_size( void ) const throw();
 pointer allocate( size_type n = 1,void *hint = 0 );
 void deallocate( pointer p,size_type n = 1 );
private:
 struct mem_node {
  void *buf;
  void **use;
  size_type num,reuse;
  struct mem_node *next;
 } *m_head;
 static mem_node &allocate0( size_type num );
 static void deallocate0( mem_node &node );
 static void finalize( mem_node &node );
 static void *allocate0( mem_node &node );
 static bool deallocate0( void *p,mem_node &node );
};
template < class T >
typename allocator2< T >::mem_node &allocator2< T >::allocate0( size_type num )
{
 char *p = new char[sizeof(mem_node)+num*(sizeof(T)+sizeof(void *))];
 mem_node &node = *reinterpret_cast< mem_node * >( p );
 node.buf = ( p += sizeof(mem_node) );
 node.use = reinterpret_cast< void ** >( p + sizeof(T)*num );
 for( size_type i = 0; i < num; ++i )
  node.use[i] = p + sizeof(T)*i;
 node.reuse = node.num = num;
 node.next = 0;
 return node;
}
template < class T >
void allocator2< T >::deallocate0( mem_node &node )
{
 char *p = reinterpret_cast< char * >( &node );
 delete[] p;
}
template < class T >
allocator2< T >::allocator2( size_type num ) throw() : m_head( &allocate0(num) )
{
}
template < class T >
void allocator2< T >::finalize( mem_node &node )
{
 if( node.next != 0 ) finalize( *node.next );
 deallocate0( node );
}
template < class T >
allocator2< T >::~allocator2( void ) throw()
{
 finalize( *m_head );
}
template < class T >
typename allocator2< T >::size_type
allocator2< T >::max_size( void ) const throw()
{
 const mem_node *node = m_head,*prev;
 while( node != 0 && node->reuse < = 0 ) prev = node,node = node->next;
 return node == 0 ? prev.num : node->reuse;
}
template < class T >
void *allocator2< T >::allocate0( mem_node &node )
{
 return node.reuse > 0 ? node.use[--node.reuse] : 0;
}
template < class T >
typename allocator2< T >::pointer
allocator2< T >::allocate( size_type,void *hint )
{
 void *p;
 mem_node *node = m_head;
 while( (p=allocate0(*node)) == 0 )
 {
  if( node->next != 0 ) node = node->next;
  else node = node->next = &allocate0( node->num );
 }
 return static_cast< pointer >( p );
}
template < class T >
bool allocator2< T >::deallocate0( void *p,mem_node &node )
{
 if( p < node.buf || p >= node.use ) return false;
 node.use[node.reuse++] = p;
 return true;
}
template < class T >
void allocator2< T >::deallocate( pointer p,size_type n )
{
 mem_node *node = m_head,*prev;
 while( !deallocate0(p,*node) ) prev = node,node = node->next;
 if( node != m_head && node->reuse >= node->num )
 {
  prev->next = node->next;
  deallocate0( *node );
 }
}

};
#endif //__MEM_POOL__

posted on 2007-03-29 14:03 终于有了间茅草棚 阅读(4572) 评论(3)  编辑 收藏

评论

# re: 简单内存对象池

写的不错!
2007-04-04 18:16 | 个性礼品

# re: 简单内存对象池

和boost的对比过没有?
2007-05-18 13:32 | ZiDing

# re: ZiDing

鉴于你的建议,前段时间我看了下boost的内存对象池,没有过于深入,
判断下来属于做法类似,性能应该相当,甚至可能我这个略好一点。

因为编写测试是一件相当麻烦,而且要求也很高的事,而要全面又很难。

boost的代码我看起来比较难读,维护、调试起来对我来说是一个大麻烦。所以,我一般不选择boost。
2007-07-06 15:56 | 清风雨
标题  
姓名  
主页
验证码 *
内容   
  登录  使用高级评论  Top
[使用Ctrl+Enter键可以直接提交]