当前位置: 首页 > news >正文

柳州做网站那家好/友情链接分析

柳州做网站那家好,友情链接分析,山西推广型网站建设,教人做甜点的网站2019独角兽企业重金招聘Python工程师标准>>> 最近在读侯捷写的《STL源码剖析》。 看完STL的内存空间分配器这章。在这章里,作者开玩笑的说,你甚至可以写一个直接从硬盘上取空间的配置器。我想,我确实可以写这样的分配器。然后今天…

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

最近在读侯捷写的《STL源码剖析》。 看完STL的内存空间分配器这章。在这章里,作者开玩笑的说,你甚至可以写一个直接从硬盘上取空间的配置器。我想,我确实可以写这样的分配器。然后今天就动手写了一个。不过这个分配器只是写着玩玩,不仅效率奇低,还有很多BUG。所以大家可以看着玩玩,可千万别使用啊。


#ifndef __ALLOCATOR_H__
#define __ALLOCATOR_H__
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <string.h>
#include <new>
#include <cstddef>
#include <cstdlib>
#include <climits>
#include <iostream>using namespace std;
namespace Costaxu
{
#define BUFFER_FILE_NAME "/tmp/costaxu_buffer"
#define BUFFER_SIZE      1024*1024*1024template <class T>inline T* _hd_allocate(ptrdiff_t size, T*, char** ppBufferCurrent){size_t totalsize=sizeof(T)*size;std::cerr<<"costaxu debug:: _hd_allocate "<<totalsize<<" bytes"<<std::endl;T* p = (T*)*ppBufferCurrent;*ppBufferCurrent += totalsize;//std::cerr<<"end _hd_allocate"<<std::endl;return p;}template <class T>inline void _hd_deallocate(T* buffer){std::cerr<<"costaxu debug:: _hd_deallocate"<<std::endl;//do nothing}template <class T1, class T2>inline void _hd_construct(T1* p, const T2& value, char** pBufferCurrent){std::cerr<<"costaxu debug:: _hd_construct"<<std::endl;//p = (T1*)*pBufferCurrent;//*pBufferCurrent += sizeof(T2);//memcpy(p,&value,sizeof(T2));cout<<"costaxu debug:: construct value is:"<<value<<endl;new(p) T1(value); cout<<"costaxu debug:: after construct p is: "<<*p<<endl;//std::cerr<<"end _hd_construct"<<std::endl;}template <class T>inline void _hd_destroy(T* ptr){std::cerr<<"costaxu debug:: _hd_destroy"<<std::endl;ptr->~T();}template <class T>class allocator{private:static char* m_pBuffer ;static char* m_pBufferCurrent;int     m_fd;public: typedef T value_type;typedef T* pointer;typedef const T* const_pointer;typedef T& reference;typedef const T& const_reference;typedef size_t   size_type;typedef ptrdiff_t difference_type;template<class U>struct rebind{typedef allocator<U> other;};void init_allocator(){m_fd = open(BUFFER_FILE_NAME, O_RDWR|O_CREAT|O_TRUNC, 0644);if(m_fd< 0 ){std::cerr<<"costaxu debug:: open "<<BUFFER_FILE_NAME<<"fail" <<std::endl;exit(1);}lseek(m_fd, BUFFER_SIZE, SEEK_SET);write(m_fd ,"0",1);m_pBuffer = (char*)mmap(0, BUFFER_SIZE, PROT_WRITE,MAP_SHARED, m_fd ,0); m_pBufferCurrent = m_pBuffer;//std::cerr<<"mmap "<<m_pBufferCurrent<<std::endl;}allocator(){if(m_pBuffer ==0){    init_allocator();}}pointer allocate(size_type n, const void* hint=0){cerr<<"costaxu debug:: allocate "<<n<<" structs"<<endl;return _hd_allocate((difference_type) n,(pointer)0, &m_pBufferCurrent);}void deallocate(pointer p,size_type n){_hd_deallocate(p);}void construct(pointer p,const T& value){_hd_construct(p,value,&m_pBufferCurrent);}void destroy(pointer p){_hd_destroy(p);}pointer address(reference x){return (pointer)&x;}const_pointer const_address(const_reference x){return (const_pointer)&x;}size_type max_size() const{return size_type(UINT_MAX/sizeof(T));}}  ;template<class T>char* allocator<T>::m_pBuffer =0;template<class T>char* allocator<T>::m_pBufferCurrent =0;
};//end of namespace Costaxu
#endif


原理是这样,我在磁盘上创建了一个'/tmp/costaxu_buffer' 这个1G大小的文件。 我在init_allocator中mmap把这个文件映射到进程内存镜像中,然后拿这个文件当作‘内存池’用。每次需要分配‘内存’的时候我就从这个文件中分配。具体的分配方式我实现的很简单,Costaxu::allocator里面的有两个静态成员变量:

static char* m_pBuffer ;
static char* m_pBufferCurrent;
这两个指针分别指向磁盘上文件'/tmp/costaxu_buffer' 的开始位置和当前已经用到的位置。每次分配一点内存,就只向后移动一下m_pBufferCurrent 这个指针。释放内存的时候我没有做任何动作。反正磁盘空间大就随便用吧。:)

使用STL容器类的时候可以用Costaxu::allocator这个模板类来分配空间,用法是这样的:

std::vector<string, Costaxu::allocator<string> > vecString;
std::vector<int,Costaxu::allocator<int> > vecInt;

这个allocator模板类主要用到4个函数allocate deallocate construct destroy , 从字面上也可以看得出就是分配空间、释放空间、构造对象和释放对象的意思。

写了个简单的程序试了一下,可以在vector这个容器里使用这个allocator。 代码如下:


#include <vector>
#include "allocator.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{//std::vector<int, Costaxu::allocator<int> > vecInt;std::vector<string, Costaxu::allocator<string> > vecString;std::vector<int,Costaxu::allocator<int> > vecInt;vecString.push_back(string("1234567890"));cout<<"vecString.push_back"<<endl;vecString.push_back("4567890");cout<<"vecString.push_back"<<endl;vecString.push_back("abcdefg");cout<<"vecString.push_back"<<endl;vecInt.push_back(10000);cout<<"vecInt.push_back"<<endl;vecInt.push_back(12345);cout<<"vecInt.push_back"<<endl;int i=0;cout<<vecString[0]<<endl;cout<<vecString[1]<<endl;cout<<vecString[2]<<endl;cout<<vecInt[0]<<endl;cout<<vecInt[1]<<endl;/* for(;i<;i++){vecInt.push_back(i);}for(i=0;i<10;i++){std::cout<<i<<std::endl;}*/ return 0;
}


然后,我测试了一下这个硬盘分配器的效率。 测试的方法是用STL默认内存分配器和我写的硬盘分配器的分别创建一个vector容器,然后向vector中插入1000万个整数。

代码如下:

int main()
{std::vector<int,Costaxu::allocator<int> > vecInt;//std::vector<int > vecInt;int i=0;  for(;i<10000000;i++){vecInt.push_back(i);}return 0;
}
在我的虚拟机(intel core duo 2.26HZ)上,

STL默认的内存分配器的vector插入1000万整数,所需要的时间是2.3秒,

而磁盘分配器运行的时间是,16.7秒。 比STL的默认内存分配器差了一个数量级啊。而且这还是在磁盘空间顺序写的情况下,如果是随机读写效率和内存差的更大了。不过relax了, 我们追求的不是效率,嗯,一方面可以学习一下STL原理,另一方面真的就是好玩了。毕竟写代码这件事情,还是有趣比较重要。


转载于:https://my.oschina.net/costaxu/blog/94716

http://www.jmfq.cn/news/4779307.html

相关文章:

  • 网站建设的要求/营销推广app
  • 哪个平台建网站比较好/湖南企业seo优化推荐
  • 专业北京网站建设公司/宁波网络营销策划公司
  • 手机网站建设公司排名/cpu游戏优化加速软件
  • 通过域名访问网站/一元友情链接平台
  • 人气页游排行榜前十名/广州seo做得比较好的公司
  • 翻译网站怎么做/乔拓云网站建设
  • 外贸展示企业网站/短视频营销策略
  • 南京网站设计工作室/seo怎么才能优化好
  • 做电商的进货网站/如何优化标题关键词
  • 深圳做关键词优化平台/关键seo排名点击软件
  • 长春市住房和城乡建设局网站/电工培训技术学校
  • 网站建设包括哪些部分/网络营销外包收费
  • 合肥最新消息/seo技巧是什么
  • 河北网站建设口碑好/附近学电脑培训班
  • 网站风格设计怎么写/seo项目经理
  • 上海知名网站制作公司/口碑营销案例2021
  • 衡水做网站的公司/品牌营销策划机构
  • 百度竞价排名是什么意思/seo推广主要做什么的
  • 北京泵网站建设/网站推广优化技巧
  • 门户网站域名是什么/windows优化大师软件介绍
  • 做废钢推广网站/seo优化培训多少钱
  • 城乡建设部网站自助商品房/惠州百度seo排名
  • 富顺住房和城乡建设厅网站/线下推广都有什么方式
  • 在网站上卖东西怎么做/成都网站优化公司
  • 网站开发与应用/全球网站排行榜
  • 西宁网站建设/关键词排名靠前
  • 建设路84号 网站备案/网站的seo是什么意思
  • 网站建设大致价格2017/百度sem认证
  • 湖南专业做网站公司/百度收录网站链接入口