Code Monkey home page Code Monkey logo

Comments (23)

pony5551 avatar pony5551 commented on May 28, 2024

这个问题好像上次zs群主提出过,也是同样的解决办法

from delphi-cross-socket.

pony5551 avatar pony5551 commented on May 28, 2024

我的fork上传了一份菜根修改的代码,可以参考一下

from delphi-cross-socket.

winddriver avatar winddriver commented on May 28, 2024

我就懒得废话了,直接上图吧
1
2
3

from delphi-cross-socket.

pony5551 avatar pony5551 commented on May 28, 2024

如果把HttpServer定义成TCrossHttpServer就会发生问题,但不代表定义成接口没问题!

先看看定义TCrossHttpServer

1

2

3

4

5

from delphi-cross-socket.

pony5551 avatar pony5551 commented on May 28, 2024

然后你上面传的图2也可以看出,AOwner: ICrossSocket传进来时是3,TIocpListen.Create后就是2了

from delphi-cross-socket.

pony5551 avatar pony5551 commented on May 28, 2024

不过如果CreateListen(Const AOwner: ICrossSocket;...
加上const也可以

from delphi-cross-socket.

pony5551 avatar pony5551 commented on May 28, 2024

这也是无意发现的问题,应该是五月定义成TCrossHttpServer才发现这个问题的

当然如果传入时 加const好像直接不调用addref和release计数为0也不释放,是不是会提高点效率?

from delphi-cross-socket.

pony5551 avatar pony5551 commented on May 28, 2024

这个也是五月的使用方法不当,这个也算delphi的接口陷阱吧

from delphi-cross-socket.

gtyhn avatar gtyhn commented on May 28, 2024

在正常使用下,最好将所有记录类型、字符、对象、接口、数组等类型以 const 定义传递能节省很大效率,防止编译器自动插入引用计数或复制副本等指令,通过调试查看汇编码的生成就能看到,所有这些在没有加 const 时才会由编译器自动插入一些指令,当然事无绝对,某些场景下可以根据需求来对 const 进行使用

from delphi-cross-socket.

pony5551 avatar pony5551 commented on May 28, 2024

受教了,谢谢楼上

from delphi-cross-socket.

 avatar commented on May 28, 2024

you can also avoid to use string as buffers, if needed to concatenate use Tstringbuilder,
avoid to pcasting string buffers using string[1], because everytime this call @uniquestring and a new @UnicodeString, you can access the string using pointer or Pbyte^ where the content is
anyway is better use a TBytes to treat the buffering, and only at the endpoint, if you need to convert to string use TEncoding.ASCII.(or UTF8).GetString(TBytes)
or you can use directly pointers with GetMem,FreeMem
also using too much strings for buffering, into a intensive operations as server, will degrade the heap

from delphi-cross-socket.

winddriver avatar winddriver commented on May 28, 2024

我之所以使用接口,就是看中了接口的自动引用计数机制,函数的接口参数我也是故意不加const修饰的,因为加了const,调用函数时引用计数就不会+1了,这个+1恰恰是我需要的,我需要在函数调用过程中,由引用计数保证接口参数一直有效

感谢各位热心的提出各种建议和意见,相信有你们的帮助,这套库会越来越好的,请继续保持热情、保持关注

from delphi-cross-socket.

pony5551 avatar pony5551 commented on May 28, 2024

我之所以使用接口,就是看中了接口的自动引用计数机制,函数的接口参数我也是故意不加const修饰的,因为加了const,调用函数时引用计数就不会+1了,这个+1恰恰是我需要的,我需要在函数调用过程中,由引用计数保证接口参数一直有效

感谢各位热心的提出各种建议和意见,相信有你们的帮助,这套库会越来越好的,请继续保持热情、保持关注

谢谢解答!

from delphi-cross-socket.

pony5551 avatar pony5551 commented on May 28, 2024

另外写idefixpack的大牛andy发表过一篇文章,是说interface速度比Object慢很多,有人建议关键单元不要用接口设计!

这个是andy发的文章:
https://andy.jgknet.de/blog/2016/05/whats-wrong-with-virtual-methods-called-through-an-interface/

from delphi-cross-socket.

gtyhn avatar gtyhn commented on May 28, 2024

Interface 这个东西怎么说呢,如果要求效率而言,肯定是没有 object 快,打个比方,一般 object 或 interface 对于子类或子接口继承关系的类型转换都是使用 as 关键字完成,而 as 如果大量使用的话是很影响性能的,但 object 可使用 MyObject := TObjectXXX(Instance) 这种方式进行强转,性能几乎不计,因为它们指向的地址是一致的,而 interface 做不到 MyIntf := IInterfaceXXX(Instance),它必须通过 as 关键字并由编译器插入 Interface.QueryInterface 查表的代码实现方式处理,具体它的内部实现可看源码,所以涉及到接口类型的转换还是涉及到一些性能问题的,这里还包括接口中方法的一些调用不像 object 那么直接等。

另外对于以接口作为参数的使用,有时应该考虑下是否需要 const 关键字的必要性,比如以下代码在使用时最好加入 const ,而减少不必要的引用计数开销:

procedure test(A: ITest);
begin
// same code...
end;

procedure main;
var
Intf: ITest;
begin
Intf := TTest.Create;
test(Intf);
end;

在某个方法中初始的接口实例,然后由该方法中的子方法执行相应的接口操作时,对接口参数不加 const 关键字完全是对性能的浪费,如果 test 中的接口参数定义为 const 传递,但在 main 方法结束后导致接口释放异常,这个锅铁定得由 main 方法中的 test 子方法背的,只要 test 方法在使用该接口参数时正常访问及传递,几乎不会出现引用计数为 0 而在子方法中被异常释放的可能性。所以接口以 const 方式传递,并在与之有关的子方法中正常调用访问,几乎不存在接口引用计数异常的问题,如果有,那就得好好检测子方法的代码使用方式了

在比如,如果真的在某个子子方法中需要接口的引用计数做特殊的操作,完全可以这样:

procedure test2(A: ITest);
begin
// 编译器插入引用计数加 1
// user same code
// 编译器插入引用计数减 1
end;

proceudre test(const A: ITest);
begin
test2(A);
end;

再或者某些结构中有对应的接口实现,并赋值,只要不特别加入 weak 或 unsafe ,编译器都会自动对结构体中的赋值插入接口引用计数代码。

所以接口参数在最顶层的方法一路传递下来时,最顶层的那个方法最好使用 const 关键符,由后面的子方法决定什么时候需要由编译器自动增加引用计数

from delphi-cross-socket.

 avatar commented on May 28, 2024

well the low level layer, cpu intensive as the sockets binded to IOCP, using base class, or TObject root without rely on interface management, we will have an enhancement
I have still not read the code, but read/write in the sockets should not lookup the interface table every time, a normal class will be faster and suitable
also consider 100K sockets, we have already one global TDictionary <Uint64, connection> at the top layer (and it's the best way to manage them for direct lookups), so let's avoid interface joining, binding, and lookup times too
(if can be done)

from delphi-cross-socket.

pony5551 avatar pony5551 commented on May 28, 2024

well the low level layer, cpu intensive as the sockets binded to IOCP, using base class, or TObject root without rely on interface management, we will have an enhancement
I have still not read the code, but read/write in the sockets should not lookup the interface table every time, a normal class will be faster and suitable
also consider 100K sockets, we have already one global TDictionary <Uint64, connection> at the top layer (and it's the best way to manage them for direct lookups), so let's avoid interface joining, binding, and lookup times too
(if can be done)

你这个问题我之前使用的方式是给基类加一个indexId,查找时根据indexId直接定位,
myobj := objects[indexId];这样就节省了查找时间

from delphi-cross-socket.

 avatar commented on May 28, 2024

I'm talking of replace Interface of the sockets binded to IOCP with a standard "class", never we should do a lookup into a list or hash, or automatic getmem freemem,
when you access the object the methods are retrieved directly through a direct jump into VMT address

at high level it's ok as now to use TDictionary for lookup ID->object, is the faster (generic associative array pair <key, pointer>)

from delphi-cross-socket.

pony5551 avatar pony5551 commented on May 28, 2024

你说的这个上面提出过,建议关键单元的基础类使用TObject而不是Interfaced

from delphi-cross-socket.

 avatar commented on May 28, 2024

we can use a lineprofiler as the nexusdb.com quality suite to see where the CPU time is involved,
often is enough to rewrite a pair of functions of a server software to obtain bottleneck free and speed raise

from delphi-cross-socket.

gtyhn avatar gtyhn commented on May 28, 2024

另外再多一句嘴,以这个框架现有的架构,将最底层抽象出的 Interface 改成 TObject,对作者不是一个简单的小活,真要调整,估计得花些时间精力

from delphi-cross-socket.

pony5551 avatar pony5551 commented on May 28, 2024

这确实是个问题,不过我看了tcp部分还是容易改的,http部分复杂了

from delphi-cross-socket.

winddriver avatar winddriver commented on May 28, 2024

抱歉,我绝不会为了这一点点性能提升而放弃接口带来的便利

若有不同意见,你们可以自己尝试改成 TObject 然后对比一下性能,你就会发现纯属浪费时间

from delphi-cross-socket.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.