| // Licensed to the Apache Software Foundation(ASF) under one |
| // or more contributor license agreements.See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership.The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| unit PerfTests; |
| |
| interface |
| |
| uses |
| Windows, Classes, SysUtils, |
| Thrift.Collections, |
| Thrift.Configuration, |
| Thrift.Test, |
| Thrift.Protocol, |
| Thrift.Protocol.JSON, |
| Thrift.Protocol.Compact, |
| Thrift.Transport, |
| Thrift.Stream, |
| ConsoleHelper, |
| TestConstants, |
| DataFactory; |
| |
| type |
| TPerformanceTests = class |
| strict private |
| FTestdata : ICrazyNesting; |
| FMemBuffer : TMemoryStream; |
| FTransport : ITransport; |
| FConfig : IThriftConfiguration; |
| |
| procedure ProtocolPeformanceTest; |
| procedure RunTest( const ptyp : TKnownProtocol; const layered : TLayeredTransport); |
| function GenericProtocolFactory(const ptyp : TKnownProtocol; const layered : TLayeredTransport; const forWrite : Boolean) : IProtocol; |
| function GetProtocolTransportName(const ptyp : TKnownProtocol; const layered : TLayeredTransport) : string; |
| public |
| class function Execute : Integer; |
| end; |
| |
| |
| implementation |
| |
| |
| // not available in all versions, so make sure we have this one imported |
| function IsDebuggerPresent: BOOL; stdcall; external KERNEL32 name 'IsDebuggerPresent'; |
| |
| |
| class function TPerformanceTests.Execute : Integer; |
| var instance : TPerformanceTests; |
| begin |
| instance := TPerformanceTests.Create; |
| instance.ProtocolPeformanceTest; |
| |
| // debug only |
| if IsDebuggerPresent then begin |
| Console.Write('Hit ENTER ...'); |
| ReadLn; |
| end; |
| |
| result := 0; |
| end; |
| |
| |
| procedure TPerformanceTests.ProtocolPeformanceTest; |
| var layered : TLayeredTransport; |
| begin |
| Console.WriteLine('Setting up for ProtocolPeformanceTest ...'); |
| FTestdata := TestDataFactory.CreateCrazyNesting(); |
| |
| for layered := Low(TLayeredTransport) to High(TLayeredTransport) do begin |
| RunTest( TKnownProtocol.prot_Binary, layered); |
| RunTest( TKnownProtocol.prot_Compact, layered); |
| RunTest( TKnownProtocol.prot_JSON, layered); |
| end; |
| end; |
| |
| |
| procedure TPerformanceTests.RunTest( const ptyp : TKnownProtocol; const layered : TLayeredTransport); |
| var freq, start, stop : Int64; |
| proto : IProtocol; |
| restored : ICrazyNesting; |
| begin |
| QueryPerformanceFrequency( freq); |
| |
| FConfig := TThriftConfigurationImpl.Create; |
| |
| proto := GenericProtocolFactory( ptyp, layered, TRUE); |
| QueryPerformanceCounter( start); |
| FTestdata.Write(proto); |
| FTransport.Flush; |
| QueryPerformanceCounter( stop); |
| Console.WriteLine( Format('RunTest(%s): write = %d msec', [ |
| GetProtocolTransportName(ptyp,layered), |
| Round(1000.0*(stop-start)/freq) |
| ])); |
| |
| restored := TCrazyNestingImpl.Create; |
| proto := GenericProtocolFactory( ptyp, layered, FALSE); |
| QueryPerformanceCounter( start); |
| restored.Read(proto); |
| QueryPerformanceCounter( stop); |
| Console.WriteLine( Format('RunTest(%s): read = %d msec', [ |
| GetProtocolTransportName(ptyp,layered), |
| Round(1000.0*(stop-start)/freq) |
| ])); |
| end; |
| |
| |
| function TPerformanceTests.GenericProtocolFactory(const ptyp : TKnownProtocol; const layered : TLayeredTransport; const forWrite : Boolean) : IProtocol; |
| var newBuf : TMemoryStream; |
| stream : IThriftStream; |
| trans : IStreamTransport; |
| const COPY_ENTIRE_STREAM = 0; |
| begin |
| // read happens after write here, so let's take over the written bytes |
| newBuf := TMemoryStream.Create; |
| if not forWrite then newBuf.CopyFrom( FMemBuffer, COPY_ENTIRE_STREAM); |
| FMemBuffer := newBuf; |
| FMemBuffer.Position := 0; |
| |
| // layered transports anyone? |
| stream := TThriftStreamAdapterDelphi.Create( newBuf, TRUE); |
| if forWrite |
| then trans := TStreamTransportImpl.Create( nil, stream, FConfig) |
| else trans := TStreamTransportImpl.Create( stream, nil, FConfig); |
| case layered of |
| trns_Framed : FTransport := TFramedTransportImpl.Create( trans); |
| trns_Buffered : FTransport := TBufferedTransportImpl.Create( trans); |
| else |
| FTransport := trans; |
| end; |
| |
| if not FTransport.IsOpen |
| then FTransport.Open; |
| |
| case ptyp of |
| prot_Binary : result := TBinaryProtocolImpl.Create(trans); |
| prot_Compact : result := TCompactProtocolImpl.Create(trans); |
| prot_JSON : result := TJSONProtocolImpl.Create(trans); |
| else |
| ASSERT(FALSE); |
| end; |
| end; |
| |
| |
| function TPerformanceTests.GetProtocolTransportName(const ptyp : TKnownProtocol; const layered : TLayeredTransport) : string; |
| begin |
| case layered of |
| trns_Framed : result := ' + framed'; |
| trns_Buffered : result := ' + buffered'; |
| else |
| result := ''; |
| end; |
| |
| case ptyp of |
| prot_Binary : result := 'binary' + result; |
| prot_Compact : result := 'compact' + result; |
| prot_JSON : result := 'JSON' + result; |
| else |
| ASSERT(FALSE); |
| end; |
| end; |
| |
| |
| end. |
| |