[c++]海量数据运行时提高程序运行效率、降低内存占用的方法

降低内存的占用

1.慎用erase()
昨天我运行了一个数据,在对字符串的处理时使用了迭代器来对string对象进行遍历,并用string.erase()进行字符串的裁剪。这种办法对于少量数据来说是完全没问题的,但是一到大量数据,就会提示内存不足,甚至电脑性能不高的话,主板会被烧坏。(别问我怎么知道的o( ̄︶ ̄)o)

出现这种情况的原因是erase对字符串(数组同理)进行擦除后,迭代器指向的是被删除的元素的下一个,而被删除的元素虽然在字符串中消失了,但是它的地址没有被释放掉,出现了野指针和内存泄漏。(自己的拙见,欢迎指导)

虽然已经找到了效率更高的办法可以不用erase,其实就是直接用find,substr就行。但是经过昨天对迭代器进行大量的研究之后,找到了以上情况的解决方案:判断迭代器所指的位置是否是字符串的开头,若不是,迭代器前移一位。

以下面的函数为例,我想去除字符串中的‘\”‘,注意:它是一个转义字符,表示双引号的一半。

原代码:

void charErase(string &str)
{
	string::iterator it;
	for (it = str.begin();it!=str.end();it++)
	{
		if(*it == '\"' )
		{
			it = str.erase(it);
			if(it == str.end())
				break;
		}
	}
}

加个判定条件:

if(it!=str.begin())
{
	 it--;
	 continue;
}

改进后的完整代码:

void charErase(string &str)
{
	string::iterator it;
	for (it = str.begin();it!=str.end();it++)
	{
		if(*it == '\"' )
		{

			it = str.erase(it);
            if(it!=str.begin())
            {
				 it--;
				 continue;
			}
			if(it == str.end())
				break;
		}
	}
}

还是不推荐用,尤其是对于处理的字符串不算长,用find和substr的效率比迭代器高。

2.释放指针后还要将指针置为空
若不置为空,那个地址还是占用着的。

free(p);
p = NULL;

3.少用公共变量,若必须用,也要及时释放
如数组vector,作为局部变量时会自动释放空间,但若作为公共变量,就会一直占用内存空间直至程序运行结束。有时候,我们虽然将其设为公共变量,但也不代表其从始至终一直有用。因此,可以选在在析构函数中释放数组的空间。

vector<数组中元素的类型>().swap(数组名);

4.不要新建多余的变量,尤其是数组等很占空间的
(1)如读文件,读一遍能解决就不要让它读两遍,费空间费时间。引申而得,我们平时在写完代码时候,要理几遍逻辑,有时虽然功能实现了,但是却做了很多无用的工作。
(2)类内定义的属性在函数中直接赋值即可,不必要在函数中新建一个相同类型的对象,再传给类内属性。这样会占用双倍空间。对于大数据量非常不友好。当然前提是该方法是类内的方法或者函数参数中有类对象。
5.多用地址传递,少用值传递。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
第1章 Symbian OS中的类命名约定 11.1 基本类型 11.2 T类 21.3 C类 31.4 R类 51.5 M类 61.6 静态类 91.7 使用者注意事项 91.8 小结 9第2章 异常退出(leave):Symbian OS的异常 102.1 异常退出函数 102.2 使用new(ELeave)进行基于堆的内存分配 122.3 构造函数与析构函数 132.4 使用异常退出函数 142.5 用TRAP和TRAPD捕获异常退出 152.6 LeaveScan 202.7 小结 21第3章 清除栈 223.1 使用清除栈 243.2 清除栈是如何工作的 273.3 对非CBase派生类使用清除栈 293.4 使用TCleanupItem实现定制清除 333.5 可移植性 353.6 对于使用转型(cast)的附加说明 353.7 小结 36第4章 两段构造 37第5章 描述符:Symbian OS中的字符串 415.1 不可修改的描述符 425.2 可修改的描述符 435.3 指针描述符 445.4 基于栈的缓冲描述符 475.5 基于堆的缓冲描述符 495.6 字面描述符 515.7 小结 54第6章 良好的描述符风格 566.1 作为参数和返回类型的描述符 576.2 一般描述符方法 586.3 使用HBufC堆描述符 616.4 外部化和内部化描述符 626.5 TFileName的过度使用 646.6 在描述符操纵方面有用的类 646.7 小结 66第7章 动态数组与缓冲区 687.1 CArrayX类 697.2 RArray和RPointerArray 737.3 为什么要用RArray代替CArrayX 777.4 动态描述符数组 787.5 定长数组 797.6 动态缓冲区 807.7 小结 82第8章 使用活动对象的事件驱动多任务 848.1 多任务基础 848.2 事件驱动多任务 858.3 使用活动对象 878.4 示例代码 908.5 没有活动调度器的线程 938.6 应用程序代码和活动对象 938.7 小结 94第9章 活动对象揭密 969.1 活动对象基础 969.2 活动对象的职责 999.3 异步服务提供者的职责 1019.4 活动调度器的职责 1019.5 启动活动调度器 1029.6 嵌套活动调度器 1029.7 扩展活动调度器 1039.8 撤销 1039.9 请求完成 1049.10 状态机 1059.11 长线任务(Long-Running Task) 1099.12 CIdle类 1119.13 CPeriodic类 1139.14 常见错误 1149.15 小结 115第10章 Symbian OS的线程与进程 11610.1 RThread类 11710.2 线程优先级 11910.3 停止一个运行的线程 12110.4 线程间数据传递 12410.5 异常处理 12610.6 进程 12610.7 小结 128第11章 客户机/服务器框架原理 12911.1 为什么会有客户机/服务器框架 12911.2 客户和服务器是如何协作的 13011.3 客户与服务器如何通信 13111.4 客户机/服务器框架使用了哪些类 13211.5 同步请求和异步请求有什么区别 13811.6 如何启动服务器 13911.7 一个客户可以有多少个连接 13911.8 当客户断开连接时会发生什么 14011.9 如果客户终止会发生什么 14011.10 如果服务器终止会发生什么 14011.11 客户机/服务器通信是如何使用线程的 14011.12 服务器空间活动对象有什么含义 14111.13 局部服务器(与客户处于同一进程中)的优点是什么 14111.14 客户机/服务器通信的开销有哪些 14111.15 一个客户在一个服务器中可以有几个当前请求 14411.16 可以对服务器功能加以扩展吗 14411.17 示例代码 14411.18 小结 145第12章 客户机/服务器框架实践 14712.1 客户机/服务器请求代码 14812.2 客户样板代码 14812.3 启动服务器并连接上客户 15512.4 服务器启动代码 15912.5 服务器类 16112.6 服务器关闭 16812.7 访问服务器 16812.8 小结 169第13章 二进制类型 17113.1 Symbian OS的EXE 17113.2 Symbian OS的DLL 17213.3 可写的静态数据 17313.4 线程局部存储(Thread-Local Storage) 17613.5 DLL装载器 17813.6 UID 17913.7 targettype限定符 18013.8 小结 182第14章 ECOM 18314.1 ECOM的架构 18314.2 ECOM接口的特性 18514.3 工厂方法 18614.4 实现一个ECOM接口 18814.5 资源文件 19014.6 示例客户代码 19214.7 小结 193第15章 严重错误(Panic) 19415.1 即时调试 19415.2 良好的严重错误风格 19515.3 Symbian OS严重错误的分类 19615.4 让另一个线程发生严重错误 19715.5 故障(fault)、异常退出和严重错误 19815.6 小结 199第16章 用断言发现bug 20016.1 _ASSERT_DEBUG 20116.2 _ASSERT_ALWAYS 20416.3 小结 205第17章 调试宏与测试类 20717.1 堆检查宏 20717.2 对象恒定宏 21117.3 用RTest进行控制台测试 21317.4 小结 216第18章 兼容性 21718.1 向前和向后兼容性 21818.2 源代码兼容性 21918.3 二进制兼容性 22018.4 防止破坏兼容性 22018.5 在不破坏二进制兼容性的情况下可以做哪些变更 22518.6 最佳实践:为未来的变化做打算 22718.7 兼容性与Symbian OS类的类别 22918.8 小结 229第19章 轻量级模板 230第20章 展示一个全面而易理解的API 23420.1 类布局 23520.2 IMPORT_C和EXPORT_C 23520.3 参数和返回值 23720.4 成员数据和功能抽象 24120.5 选择类、方法和参数的名字 24420.6 编译器生成的函数 24520.7 小结 246第21章 良好的编码风格 24821.1 减小代码尺寸 24821.2 小心地使用堆内存 25021.3 小心地使用栈内存 25421.4 消除子表达式,最大化代码效率 25621.5 推迟优化 25821.6 小结 258附录1 代码检查列表 259类的声明 259头文件 259注释 260构造函数 260析构函数 260分配与删除 260清除栈和异常退出安全 261循环与程序流控制 261程序逻辑 262描述符 262容器 263附录2 术语表 264附录3 参考书目及在线资源 267

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值