\t\tHook TStream类的copyfrom,大大提高效率

2024-02-14 07:32

本文主要是介绍\t\tHook TStream类的copyfrom,大大提高效率,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Hook TStream类的copyfrom,大大提高效率

此文原创,转载请注明出处

作者:二娃

之前关于这遍博文的内容我曾发表在盒子论坛内,现在利用这段时间好好写下来,以备大家一起来来研究,

我在用Remobjects做服务端项目时,发现Remobject服务端代码有一个执行的瓶颈,它用到很多TStream类的copyfrom这个成员函数,这个Copyfrom在整个客户端挤占了1/3的耗时.打个比方,

copyfrom工作原理是申请一块最大为$F000内存空间,从源stream内读一块内容到这块内存空间上,目标stream再写入这块内存上的内容到自身的内容,然后销毁这块内存,如此反复,直到源stream读被读完,这对于两个stream都是如filestream一样非含有本身的内存存储stream是有好处的,我想borland在写copyfrom这个函数时是基于这个考虑的,但是这种方法会大大降低代码的效率,原因就出在不停地申请缓冲区内存。

再仔细研究了Remobject用到copyfrom的地方,发现与之对应的两个stream至少一个是继承自TCustomMemoryStream,由于就联想到能否用TCustomMemoryStream代替父类TStream来操作copyfrom,这是因为TCustomMemoryStream有个属性叫memory,这是一个指针,指向实际该stream的内容,只要是能到内容的指针,在地址上的内容访问就变得很简单,

本来我想写一个继承自TMemoryStream的stream类,重写copyfrom方法,但是发现在TStream的copyfrom的成员函数后面没有virturl,abstract,连override都没有,所以写这个方法的覆盖就要用到reintroduce,但是这样也麻烦,因为我不能为每个第三方代码内的stream重写copyfrom方法,

还好在这里cnpack的zjy等大侠提供了一个TCnMethodhook的类(关于地址的hook请参阅其它的网上文章,这里不作讨论),那剩下事只要我将copyfrom写好,然后去hook TStream类的copyfrom,这样,只要我项目中用到stream的copyfrom地方,我就不用改动任何第三方代码的源码就能达到目的,

以下内容为 hook copyfrom的单元,直接此用到单元下就ok,目前在若干项目中测试过,能将remobject的用到copyfrom的地方的耗时降低的不计的程度

//代码开始

unit uCnFastStream;

interface

implementation

uses

Classes,CnMethodHook;

type

TStreamCopyFromFun= function(Slf:TStream; Source: TStream; Count: Int64): Int64;

var

_CnStreamCopyFromHook:TCnMethodHook;

_OldStreamCopyFromFun:TStreamCopyFromFun;

function CnFastStreamCopyFrom(Slf, Source: TStream; Count: Int64): Int64;

var

aRealSize:Int64;

aSlfStream:TCustomMemoryStream absolute Slf;

aSourceStream:TCustomMemoryStream absolute Source;

begin

if Count = 0 then

begin

Source.Position := 0;

Count := Source.Size;

end;

Result:=Count;

//注意此方法能工作的首要条件是Slf, Source两者之一是TCustomMemoryStream,否则调用原函数

//判断Slf或Source是不是TCustomMemoryStream,如果是的话,直接从Memory的地址上进行操作 ,

//因为CustomMemoryStream 的read或writer都用到System.move

//这样省去了原TStream不停地创建和写buffer 及设置Capacity ,原copyfrom这里最浪费时间

//用此方法可直接将Source的内存块追加到Slf的Memory地址的后面

aRealSize:=Source.Size-Source.Position;

if Result>aRealSize then

Result:=aRealSize;

//如果没有数据需要与入,就退出

if Result=0 then

Exit;

if (Slf is TCustomMemoryStream)

then

begin

//先设置内存的大小,将slf.Memory扩大,不然下面找不到地址

Slf.Size:=Slf.Position+Result;

//source直接从slf.memory后面写

Result:=Source.Read(Pointer(Longint(aSlfStream.Memory) + Slf.Position)^,Result);

Slf.Position:=Slf.Position+Result; //将Slf Position推后

Slf.Size:=Slf.Position;

end

else

//如果没有Memory 则可能有另外的处理方式, 如果TADOBlobStream

if (Source is TCustomMemoryStream) and Assigned(aSourceStream.Memory)

then

begin

//直接写入到Slf的地址内

Result:=Slf.Write(Pointer(Longint(aSourceStream.Memory) + Source.Position)^,Result);

Source.Position:=Source.Position+Result; //将Source Position推后

end

else

begin

//如果两者皆不是,用原有的copyfrom进行处理

_CnStreamCopyFromHook.UnhookMethod;

try

Result:=_OldStreamCopyFromFun(Slf,Source,Result);

finally

_CnStreamCopyFromHook.HookMethod;

end;

end;

end;

initialization

_OldStreamCopyFromFun:=CnGetBplMethodAddress(@TStream.CopyFrom);

_CnStreamCopyFromHook:=TCnMethodHook.Create(@_OldStreamCopyFromFun,@CnFastStreamCopyFrom);

finalization

_CnStreamCopyFromHook.Free;

_CnStreamCopyFromHook:=nil;

end.

//代码结束

这篇关于\t\tHook TStream类的copyfrom,大大提高效率的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/707876

相关文章

stl的sort和手写快排的运行效率哪个比较高?

STL的sort必然要比你自己写的快排要快,因为你自己手写一个这么复杂的sort,那就太闲了。STL的sort是尽量让复杂度维持在O(N log N)的,因此就有了各种的Hybrid sort algorithm。 题主你提到的先quicksort到一定深度之后就转为heapsort,这种是introsort。 每种STL实现使用的算法各有不同,GNU Standard C++ Lib

Hbase Filter+Scan 查询效率优化

Hbase Filter+Scan 查询效率问题 众所周知,Hbase利用filter过滤器查询时候会进行全表扫描,查询效率低下,如果没有二级索引,在项目中很多情况需要利用filter,下面针对这种情况尝试了几种优化的方案,仅供参考,欢迎交流。 根据业务要求,作者需要根据时间范围搜索所需要的数据,所以作者设计的rowKey是以时间戳为起始字符串的。 正确尝试: 1.scan 设置 开始行和结

如何提高开发的效率,让老板不知所措的给你发工资

设计模式 UML JSP 编程 数据结构 1.你可能会常常发现,写了一段代码后,编译程序时是一大堆的出错 (原因:语法不熟)  ──别担心,这是每个程序员必须经历的事,这时候你就需要更大的耐心及细心,对每一行代码进行仔细人阅读并改正,这个很重要,这可以培养你的理解代码能力,所以要常读程序,不要等到程序运行以后才知道你的程序的结果。  ──如何避免:在写代码以前,要认真的学习计算机语

算法复杂度 —— 数据结构前言、算法效率、时间复杂度、空间复杂度、常见复杂度对比、复杂度算法题(旋转数组)

目录 一、数据结构前言 1、数据结构 2、算法 3、学习方法 二、 算法效率 引入概念:算法复杂度  三、时间复杂度 1、大O的渐进表示法 2、时间复杂度计算示例  四、空间复杂度 计算示例:空间复杂度 五、常见复杂度对比 六、复杂度算法题(旋转数组) 1、思路1 2、思路2 3、思路3 一、数据结构前言 1、数据结构         数据结构(D

msyql执行效率的问题以及常见基础面试题目

SQL被称为结构化查询语言(Structured Query Language )是操作和检索关系型数据库的标准语言 SQL语言包括三种主要程序设计语言类别的语句:数据定义语言(DDL),数据操作语言(DML)及数据控制语言(DCL)。 ※ 数据定义语言(DDL),例如:CREATE、DROP、ALTER等语句。    Data Definition Language ※ 数据

Axure元件库Ant Design中后台原型模板:提升设计与开发效率的利器

企业对于中后台产品的设计与开发需求日益增长。为了提升用户体验和开发效率,设计者和开发者们不断寻求更加高效、统一的解决方案。Ant Design,作为阿里巴巴开源的一套企业级UI设计语言和React组件库,凭借其丰富的组件和统一的设计风格,已成为众多项目的首选。而在Axure中使用Ant Design元件库,更是为中后台产品的原型设计带来了极大的便利。 Ant Design简介 Ant D

如何通过食堂采购小程序端降低成本,提升效率?

随着数字化管理工具的普及,越来越多的食堂正在引入小程序来优化采购流程,减少成本和提升效率。食堂采购小程序端通过技术手段实现了自动化、智能化的管理方式,为管理者提供了极大的便利。本文将探讨如何利用技术手段开发一个高效的食堂采购小程序端,并提供一些代码示例,帮助你理解其背后的实现原理。 1. 简化采购流程 在食堂采购小程序中,简化采购流程是核心目标之一。我们可以利用数据库和后端服务来实现快速下单

【C++】优化函数对象:提升性能和内存效率

函数对象 =》c语言里面的函数指针对象构造优化对象使用过程中背后调用的方法函数调用过程中对象背后调用方法:优化原则move,forward 函数对象 =》c语言里面的函数指针 通过函数对象调用operator(),可以省略函数的调用开销,比通过函数指针调用函数(不能够inline内联调用)效率高因为函数对象是用类生成的,所有还可以添加相关的成员变量,用来记录函数对象使用时的更

如何限制与管控员工上网行为?四个方法让员工效率倍增!【企业员工上网行为管理】

在信息化时代,员工的上网行为直接影响着工作效率和企业的安全性。不当的网络使用,如浏览与工作无关的网站、下载不安全的文件,可能导致工作效率低下,甚至引发安全风险。因此,许多企业正在积极寻找有效的措施来管控员工的上网行为,以确保工作效率的提升。 以下是四个常见且有效的员工上网行为管理方法,帮助企业实现更高效的网络管理。 方法一:配置网络防火墙进行访问限制 最基础的员工上网行为管理方法是通过配置防

io本质+io效率本质,5种io模型(介绍,异步/同步区别,阻塞/非阻塞区别)

目录 5种io模型 io引入 io的本质 io效率的本质 模型引入 以钓鱼为例 效率最高的方式 异步io和同步io的区别 阻塞式和非阻塞式io的区别 介绍 阻塞式io ​编辑 非阻塞式io ​编辑 信号驱动式io ​编辑 多路转接/复用 ​编辑 异步io 5种io模型 io引入 io的本质 以read ,write为例: 如果底层缓冲区没有数据