178 lines
5.3 KiB
ObjectPascal
178 lines
5.3 KiB
ObjectPascal
// 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.
|
|
|