blob: e485212b0c0be8d73f091c6091b2e7f0493e2953 [file] [log] [blame]
// 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.