![]() |
TCP Indy Client/Server Performanceproblem
Ahoj, liebe Gemeinde
Derzeit muß ich einen Cache entwickeln, der per TCP mit clients kommuniziert. Er soll aus einer DB nur die Daten laden, die sich verändert haben usw.... Die erste Testanwendung habe ich mit Datasnap und einer TSocketConnection gemacht: Für ca. 5.5MB Daten verbrät das Teil 1600ms (ca. 3.4MB/sec). Ups, dachte ich mir geht das nicht schneller? (ich hab ein 100mb Netz, und Dateien kopieren kann ich mit 8MB/sec). Also Mal die Indies angeschaut, is ja simpel, einen TCPServer in den Cache-Manager, einen TCP-Client in den Test-Client und ab gehts.. ... Denkste. Genauso 'schnell'. So sieht der Code aus.
Delphi-Quellcode:
Und im Client (Button-Ereignis)
Procedure TfmMain.TCPSvrExecute(AThread: TIdPeerThread);
Var sQuery, sResponse : String; Begin With AThread.Connection Do Begin sQuery := ReadLn; LoadData (sQuery, sResponse); c := GetTickCount; WriteLn(sResponse); lbInfo.caption := IntToStr(GetTickCount - c)+' Tics'; // <--- Zeigt 40ms Disconnect; End; End;
Delphi-Quellcode:
Sind da die Indies an ihren Grenzen oder kann man irgendwo etwas tunen?
Procedure TForm6.btTCPClick(Sender: TObject);
Var sResponse, sQuery : WideString; c: Cardinal; Begin c := GetTickCount; sQuery := 'Auftragsdaten'; With TCPClnt Do Begin Try Connect; WriteLn(sQuery); c := GetTickCount; sResponse := ReadLn; lbInfo.Caption := IntToStr(GetTickCount - c) + ' tics';// <-- 1670 Tics Finally Disconnect; End; End; End Danke im Voraus. |
Re: TCP Indy Client/Server Performanceproblem
Ich vermute mal es ohne ausgaben in der schliefe...
bei einem alten project, es ging darum mysql datensätzte in eien ini datei zu schrieben, hatte ich mich auch gewundert warum es so lange dauerte... Durch lages hin und hertesten habe ich herausgefunden das es die ausgaben waren die das ganze gestoppt hatten. Als ich die ausgaben... also habe ihc die ausgaben weggelassen.. und schwupps.. das ganze war in 12 sekunden fertig, vorher hat es um die 8 min gedauert. Also einfach mal die ausgaben auskommatieren, und erst nach ablauf der schleifen den engültigen wert anzeigen |
Re: TCP Indy Client/Server Performanceproblem
Welche Ausgaben? Da sind keine ....
|
Re: TCP Indy Client/Server Performanceproblem
lbinfo.caption z.b.
ich weiß nu nicht das du ja sagtest sind es 5.5. mb.. sie wird er ja nicht mit einmal auslesen können also macht er es in ner schleife.... in der du dan auch die caption aktualisierst... oder ich habe den ganzen kram falsch verstanden... wenn ja, dann sorry, habe noch nicht mit indy's gearbeitet.. mache das alles mit sockets |
Re: TCP Indy Client/Server Performanceproblem
Die 5.5MB gehen in einem Rutsch rüber. Mit 3.3MB/sec
|
Re: TCP Indy Client/Server Performanceproblem
wir reden doch hier über eine netzwerkübertragung richtig ?
also ist es quasi ein sendstream, und er holt dsich also die db daten und verschickt diese dann.... ich weiß nun nicht wie groß der puffer ist... aber 5mb... und das onread ereigns durchläuft jede ms den puffer und holt die daten raus... ok es kann sein das es bei den indies ein wenig anders funktioniert.. ich hatte bei einer datei von 2.4 mb größe, über 30 durchläufe |
Re: TCP Indy Client/Server Performanceproblem
Hallo!
Probiere es mal mit Streams anstelle der Methoden ReadLn/WriteLn. Also Write(Stream) und ReadStream einsetzen... Cu, Udontknow |
Re: TCP Indy Client/Server Performanceproblem
Hallo,
Ich habe nun ReadStream/WriteStream benutzt, sowie den SendBuffer/Receivebuffer auf 1MB gesetzt. Bringt nichts. Dann habe ich die Daten mit ZLib komprimiert. Inklusive Overhead fürs komprimieren und dekomprimieren steigt dadurch der Bruttodurchsatz auf >5MB/sec und das geht ja. |
Re: TCP Indy Client/Server Performanceproblem
Nochmal zum Code oben:
Wenn der Client die Anfrage losschickt, wird ja auf Serverseite vor dem GetTickcount LoadData aufgerufen. Evtl braucht er aber dafür auch Zeit, die du dann natürlich nur im Client-Zeitfenster siehst. Währenddessen wartet der Client ja bereits, sodaß eben die Zeit für LoadData mit im Tickcount des Clients ist. Da das sehr wahrscheinlich eine Datenbankabfrage ist, wird hier bestimmt die eine oder andere Millisekunde vergehen. Cu, Udontknow |
Re: TCP Indy Client/Server Performanceproblem
Schau nochmal genau hin: Ich messe auf Serverseite die reine Zeit, die für's verschicken drauf geht (die interessiert mich gar nicht, sie dient nur zum Vergleich).
Auf Clientseite wird die Zeit gemessen, die für das ReadStream verbraten wird (nun gut, das Label.Caption setzen ist auch dabei). |
Re: TCP Indy Client/Server Performanceproblem
Hmmm... Gehen wir es mal genau durch.
Client: Sendet Query, führt GetTickcount durch und wartet auf Ergebnis (Aufruf von ReadStream). Server: Wartet auf Anfrage. Bei Erhalt wird LoadData aufgerufen und das Ergebnis dann versendet. Die Clientzeit enthält also die Zeit von LoadData + Versand. Wenn du immer noch skeptisch bist: : Bau mal nach dem LoadData, aber vor dem Server-Gettickcount ein Sleep(10000) ein. Wetten, daß die Clientzeit um 10 Sekunden hochgeht? ;-) Nur weil du auf Clientseite nun Readstream aufgerufen hast, bedeutet das doch noch lange nicht, daß der Server bereits mit dem Versand der Daten beschäftigt ist. Cu, Udontknow |
Re: TCP Indy Client/Server Performanceproblem
Ah, jetzt weiß ich, was Du meinst ... :wall:
Ich prüf das morgen nochmal.... Ich meine, das LoadData sind ca. 250ms, dann wären 5.5MB in ca 1300 ms beim Client... Auch zu lahm, aber besser. Ich meld mich morgen |
Re: TCP Indy Client/Server Performanceproblem
So, nochmal geprüft. Die Nettoübertragung liegt bei 1300ms für 5.5MB, ergo 4.2MB/sec, und das ist immer noch zu wenig.
:gruebel: |
Re: TCP Indy Client/Server Performanceproblem
Hallo!
Was für eine Art Stream nutzt du? TMemoryStream? Postest du bitte mal die neuen Sende- und Empfangsroutinen? Bis dann, Andreas |
Re: TCP Indy Client/Server Performanceproblem
Hallo nochmal,
habe eine kleine Testanwendung geschrieben, um die Performance zu prüfen. Ist natürlich auch abhängig von der Hardware (Einstellung der Netzwerkkarten: 100 Mbit/s Vollduplex). Ergebnis: Client und Server lokal: 10 MB in 234 Ticks. (42 MB/s) Client auf anderer Maschine: 10 MB in 875 Ticks. (11 MB/s). Das ist nahe am Maximalwert (100 Mbit / 8 = 12.5 MByte). Hier mal der Code, ist allerdings die neuere Indy-Version und muss dementsprechend angepasst werden... Client:
Delphi-Quellcode:
Server:
procedure TForm67.Button1Click(Sender: TObject);
var Command:Integer; var Stream:TMemoryStream; var Size:Int64; var c:cardinal; begin Command:=0; TCPClient.Connect; TCPClient.IOHandler.Write(Command); Stream:=TMemoryStream.Create; try Size:=TCPClient.IOHandler.ReadInt64; Memo1.Lines.Add('Empfange '+IntToStr(Size)+' Bytes'); Stream.Size:=Size; c := GetTickCount; TCPClient.IOHandler.ReadStream(Stream,Size); Memo1.Lines.Add(IntToStr(GetTickCount - c) + ' tics'); finally Stream.Free; end; end;
Delphi-Quellcode:
Bis dann,
var Stream:TMemoryStream;
begin AContext.Connection.IOHandler.ReadInteger(); Stream:=TMemoryStream.Create; try Stream.Size:=1024*1024*10; AContext.Connection.IOHandler.Write(Stream.Size); AContext.Connection.IOHandler.Write(Stream,Stream.Size); AContext.Connection.Disconnect; finally Stream.Free; end; Andreas |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:19 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz