Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple Counters #115

Open
tigerclawn82 opened this issue May 4, 2016 · 14 comments
Open

Multiple Counters #115

tigerclawn82 opened this issue May 4, 2016 · 14 comments

Comments

@tigerclawn82
Copy link

Hi,
I have created multiple Perf Methods in single POCO. I am getting following output in console which have exceptions

------------ STARTING TestAndPerf.Perf.PerfLogging+Perf_Logger_Val ----------
ERROR: Error occurred during $TestAndPerf.Perf.PerfLogging+Perf_Logger_Val SETUP
.
NBench.NBenchException: error while retrieving counter ---> System.Collections.G
eneric.KeyNotFoundException: The given key was not present in the dictionary.
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at NBench.BenchmarkContext.GetCounter(String name)
   --- End of inner exception stack trace ---
   at NBench.BenchmarkContext.GetCounter(String name)
   at TestAndPerf.Perf.PerfLogging.Setup(BenchmarkContext context) in D:\Develop
ment\Production-WS\Infrastructure\TestAndPerf\Perf\PerfLogging.cs:line 21
   at NBench.Sdk.ReflectionBenchmarkInvoker.InvokePerfSetup(BenchmarkContext con
text)
   at NBench.Sdk.ReflectionBenchmarkInvoker.InvokePerfSetup(Int64 runCount, Benc
hmarkContext context)
   at NBench.Sdk.Benchmark.PreRun()
--------------- BEGIN WARMUP ---------------
Elapsed: 00:00:00.6864496
TotalBytesAllocated - bytes: 231,480.00 ,bytes: /s 337,213.35 , ns / bytes: 2,96
5.48
TotalCollections [Gen2] - collections: 0.00 ,collections: /s 0.00 , ns / collect
ions: 686,449,682.04
[Counter] Counter_Logger_Val - operations: 1.00 ,operations: /s 1.46 , ns / oper
ations: 686,449,682.04
--------------- END WARMUP ---------------

WARNING: Error during previous run of TestAndPerf.Perf.PerfLogging+Perf_Logger_V
al. Aborting run...
--------------- RESULTS: TestAndPerf.Perf.PerfLogging+Perf_Logger_Val ----------
-----
Test to ensure that minimal Througput of __.Val is sufficient
--------------- DATA ---------------
TotalBytesAllocated: Max: 231,480.00 bytes, Average: 231,480.00 bytes, Min: 231,
480.00 bytes, StdDev: 0.00 bytes
TotalBytesAllocated: Max / s: 337,213.35 bytes, Average / s: 337,213.35 bytes, M
in / s: 337,213.35 bytes, StdDev / s: 0.00 bytes

TotalCollections [Gen2]: Max: 0.00 collections, Average: 0.00 collections, Min:
0.00 collections, StdDev: 0.00 collections
TotalCollections [Gen2]: Max / s: 0.00 collections, Average / s: 0.00 collection
s, Min / s: 0.00 collections, StdDev / s: 0.00 collections

[Counter] Counter_Logger_Val: Max: 1.00 operations, Average: 1.00 operations, Mi
n: 1.00 operations, StdDev: 0.00 operations
[Counter] Counter_Logger_Val: Max / s: 1.46 operations, Average / s: 1.46 operat
ions, Min / s: 1.46 operations, StdDev / s: 0.00 operations

--------------- ASSERTIONS ---------------
[FAIL] Expected [Counter] Counter_Logger_Val to must be greater than 1,000,000.0
0 operations; actual value was 1.46 operations.
[PASS] Expected TotalBytesAllocated to must be less than or equal to 16,384,000.
00 bytes; actual value was 231,480.00 bytes.
[PASS] Expected TotalCollections [Gen2] to must be exactly 0.00 collections; act
ual value was 0.00 collections.
--------------- EXCEPTIONS ---------------
NBench.NBenchException: Error occurred during $TestAndPerf.Perf.PerfLogging+Perf
_Logger_Val SETUP. ---> NBench.NBenchException: error while retrieving counter -
--> System.Collections.Generic.KeyNotFoundException: The given key was not prese
nt in the dictionary.
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at NBench.BenchmarkContext.GetCounter(String name)
   --- End of inner exception stack trace ---
   at NBench.BenchmarkContext.GetCounter(String name)
   at TestAndPerf.Perf.PerfLogging.Setup(BenchmarkContext context) in D:\Develop
ment\Production-WS\Infrastructure\TestAndPerf\Perf\PerfLogging.cs:line 21
   at NBench.Sdk.ReflectionBenchmarkInvoker.InvokePerfSetup(BenchmarkContext con
text)
   at NBench.Sdk.ReflectionBenchmarkInvoker.InvokePerfSetup(Int64 runCount, Benc
hmarkContext context)
   at NBench.Sdk.Benchmark.PreRun()
   --- End of inner exception stack trace ---

## Exceptions
------------ FINISHED TestAndPerf.Perf.PerfLogging+Perf_Logger_Val ----------
------------ STARTING TestAndPerf.Perf.PerfLogging+Test_Logger_DB ----------
ERROR: Error occurred during $TestAndPerf.Perf.PerfLogging+Test_Logger_DB SETUP.

NBench.NBenchException: error while retrieving counter ---> System.Collections.G
eneric.KeyNotFoundException: The given key was not present in the dictionary.
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at NBench.BenchmarkContext.GetCounter(String name)
   --- End of inner exception stack trace ---
   at NBench.BenchmarkContext.GetCounter(String name)
   at TestAndPerf.Perf.PerfLogging.Setup(BenchmarkContext context) in D:\Develop
ment\Production-WS\Infrastructure\TestAndPerf\Perf\PerfLogging.cs:line 20
   at NBench.Sdk.ReflectionBenchmarkInvoker.InvokePerfSetup(BenchmarkContext con
text)
   at NBench.Sdk.ReflectionBenchmarkInvoker.InvokePerfSetup(Int64 runCount, Benc
hmarkContext context)
   at NBench.Sdk.Benchmark.PreRun()
ERROR: Error occurred during $TestAndPerf.Perf.PerfLogging+Test_Logger_DB RUN.
System.NullReferenceException: Object reference not set to an instance of an obj
ect.
   at TestAndPerf.Perf.PerfLogging.Test_Logger_DB(BenchmarkContext context) in D
:\Development\Production-WS\Infrastructure\TestAndPerf\Perf\PerfLogging.cs:line
51
   at NBench.Sdk.Benchmark.RunBenchmark()
   at NBench.Sdk.Benchmark.RunSingleBenchmark()
--------------- BEGIN WARMUP ---------------
Elapsed: 00:00:00.0077538
TotalBytesAllocated - bytes: -6,595,792.00 ,bytes: /s -16,066,096,111,520.00 , n
s / bytes: 410.54
TotalCollections [Gen2] - collections: 0.00 ,collections: /s 0.00 , ns / collect
ions: 410.54
[Counter] Counter_Logger_DB - operations: 0.00 ,operations: /s 0.00 , ns / opera
tions: 410.54
--------------- END WARMUP ---------------

WARNING: Error during previous run of TestAndPerf.Perf.PerfLogging+Test_Logger_D
B. Aborting run...
--------------- RESULTS: TestAndPerf.Perf.PerfLogging+Test_Logger_DB -----------
----
Test to ensure that minimal Througput of __.DB is sufficient
--------------- DATA ---------------
TotalBytesAllocated: Max: -6,595,792.00 bytes, Average: -6,595,792.00 bytes, Min
: -6,595,792.00 bytes, StdDev: 0.00 bytes
TotalBytesAllocated: Max / s: -16,066,096,111,520.00 bytes, Average / s: -16,066
,096,111,520.00 bytes, Min / s: -16,066,096,111,520.00 bytes, StdDev / s: 0.00 b
ytes

TotalCollections [Gen2]: Max: 0.00 collections, Average: 0.00 collections, Min:
0.00 collections, StdDev: 0.00 collections
TotalCollections [Gen2]: Max / s: 0.00 collections, Average / s: 0.00 collection
s, Min / s: 0.00 collections, StdDev / s: 0.00 collections

[Counter] Counter_Logger_DB: Max: 0.00 operations, Average: 0.00 operations, Min
: 0.00 operations, StdDev: 0.00 operations
[Counter] Counter_Logger_DB: Max / s: 0.00 operations, Average / s: 0.00 operati
ons, Min / s: 0.00 operations, StdDev / s: 0.00 operations

--------------- ASSERTIONS ---------------
[FAIL] Expected [Counter] Counter_Logger_DB to must be greater than 1,000,000.00
 operations; actual value was 0.00 operations.
[PASS] Expected TotalBytesAllocated to must be less than or equal to 16,384,000.
00 bytes; actual value was -6,595,792.00 bytes.
[PASS] Expected TotalCollections [Gen2] to must be exactly 0.00 collections; act
ual value was 0.00 collections.
--------------- EXCEPTIONS ---------------
NBench.NBenchException: Error occurred during $TestAndPerf.Perf.PerfLogging+Test
_Logger_DB SETUP. ---> NBench.NBenchException: error while retrieving counter --
-> System.Collections.Generic.KeyNotFoundException: The given key was not presen
t in the dictionary.
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at NBench.BenchmarkContext.GetCounter(String name)
   --- End of inner exception stack trace ---
   at NBench.BenchmarkContext.GetCounter(String name)
   at TestAndPerf.Perf.PerfLogging.Setup(BenchmarkContext context) in D:\Develop
ment\Production-WS\Infrastructure\TestAndPerf\Perf\PerfLogging.cs:line 20
   at NBench.Sdk.ReflectionBenchmarkInvoker.InvokePerfSetup(BenchmarkContext con
text)
   at NBench.Sdk.ReflectionBenchmarkInvoker.InvokePerfSetup(Int64 runCount, Benc
hmarkContext context)
   at NBench.Sdk.Benchmark.PreRun()
   --- End of inner exception stack trace ---
NBench.NBenchException: Error occurred during $TestAndPerf.Perf.PerfLogging+Test
_Logger_DB RUN. ---> System.NullReferenceException: Object reference not set to
an instance of an object.
   at TestAndPerf.Perf.PerfLogging.Test_Logger_DB(BenchmarkContext context) in D
:\Development\Production-WS\Infrastructure\TestAndPerf\Perf\PerfLogging.cs:line
51
   at NBench.Sdk.Benchmark.RunBenchmark()
   at NBench.Sdk.Benchmark.RunSingleBenchmark()
   --- End of inner exception stack trace ---

## Exceptions
------------ FINISHED TestAndPerf.Perf.PerfLogging+Test_Logger_DB ----------

I have used following code, please help if there is any issue in my setup or if i am missing something

public class PerfLogging
    {
        private Counter Counter_Logger_Val;
        private Counter Counter_Logger_DB;

        [PerfSetup]
        public void Setup(BenchmarkContext context)
        {
            Counter_Logger_Val = context.GetCounter("Counter_Logger_Val");
            Counter_Logger_DB = context.GetCounter("Counter_Logger_DB");
        }

        [PerfBenchmark(Description = "Test to ensure that minimal Througput of __.Val is sufficient",
        NumberOfIterations = 3, RunMode = RunMode.Throughput,
        RunTimeMilliseconds = 1000, TestMode = TestMode.Test)]
        [CounterThroughputAssertion("Counter_Logger_Val", MustBe.GreaterThan, 1000000d)]
        [MemoryAssertion(MemoryMetric.TotalBytesAllocated, MustBe.LessThanOrEqualTo, ByteConstants.SixteenKb * 1000)]
        [GcTotalAssertion(GcMetric.TotalCollections, GcGeneration.Gen2, MustBe.ExactlyEqualTo, 0.0d)]
        public void Perf_Logger_Val(BenchmarkContext context)
        {
            Assert.Equal(__.Val(Logger.Level.NotSpecified), "NotSpecified");
            string[] values = { "", null, "A" };
            Assert.Equal(__.Val(values), "A");
            Assert.Equal(__.Val(false, values), "");
            Counter_Logger_Val.Increment();
        }

        [PerfBenchmark(Description = "Test to ensure that minimal Througput of __.DB is sufficient",
        NumberOfIterations = 3, RunMode = RunMode.Throughput,
        RunTimeMilliseconds = 1000, TestMode = TestMode.Test)]
        [CounterThroughputAssertion("Counter_Logger_DB", MustBe.GreaterThan, 1000000d)]
        [MemoryAssertion(MemoryMetric.TotalBytesAllocated, MustBe.LessThanOrEqualTo, ByteConstants.SixteenKb * 1000)]
        [GcTotalAssertion(GcMetric.TotalCollections, GcGeneration.Gen2, MustBe.ExactlyEqualTo, 0.0d)]
        public void Test_Logger_DB(BenchmarkContext context)
        {
            Assert.Equal(__.DB("DB", "USER", "PASSWORD"), "USER/********@DB");
            typeof(Options).GetField("_ShowPassword", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static).SetValue(null, 1);
            Assert.Equal(__.DB("DB", "USER", "PASSWORD"), "USER/PASSWORD@DB");
            typeof(Options).GetField("_ShowPassword", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static).SetValue(null, 0);
            Counter_Logger_DB.Increment();
        }
    }

Any help would be appreciated, Thanks

@Aaronontheweb
Copy link
Member

Here's your problem:

context.GetCounter("Counter_Logger_DB");

You need to declare a CounterMeasurement or CounterThroughputAssertion for every counter.

@tigerclawn82
Copy link
Author

Hi,

 [CounterThroughputAssertion("Counter_Logger_DB", MustBe.GreaterThan, 1000000d)]

is used in both methods but not CounterMeasurement do i need to add that attribute too?

@tigerclawn82
Copy link
Author

Hi,
Tried adding CounterMeasurement to both methods but same error appears. It would be really helpful if any eg would be provided where in single class multiple benchmarking methods with own counters.

Thanks

@Aaronontheweb
Copy link
Member

@tigerclawn82 good feedback. Let me put an example on this thread real quick.

@Aaronontheweb
Copy link
Member

Aaronontheweb commented Jun 1, 2016

public class TcpServerSocketChannelHorizontalScaleSpec
    {
        static TcpServerSocketChannelHorizontalScaleSpec()
        {
            // Disable the logging factory
            LoggingFactory.DefaultFactory = new NoOpLoggerFactory();
        }

        private static readonly IPEndPoint TEST_ADDRESS = new IPEndPoint(IPAddress.IPv6Loopback, 0);

        protected ClientBootstrap ClientBootstrap;
        protected ServerBootstrap ServerBoostrap;

        protected IEventLoopGroup ClientGroup;
        protected IEventLoopGroup WorkerGroup;
        protected IEventLoopGroup ServerGroup;

        private const string ClientConnectCounterName = "connected clients";
        private Counter _clientConnectedCounter;

        private const string InboundThroughputCounterName = "inbound ops";
        private Counter _inboundThroughputCounter;

        private const string OutboundThroughputCounterName = "outbound ops";
        private Counter _outboundThroughputCounter;

        private const string ErrorCounterName = "exceptions caught";
        private Counter _errorCounter;

        private IChannel _serverChannel;
        private ConcurrentBag<IChannel> _clientChannels;
        private CancellationTokenSource _shutdownBenchmark;
        protected readonly ManualResetEventSlim ResetEvent = new ManualResetEventSlim(false);

        public const int IterationCount = 1; // these are LONG-running benchmarks. stick with a lower iteration count

        // Sleep main thread, then start a new client every 30 ms
        private static readonly TimeSpan SleepInterval = TimeSpan.FromMilliseconds(300);

        /// <summary>
        /// If it takes longer than <see cref="SaturationThreshold"/> to establish 10 connections, we're saturated.
        /// 
        /// End the stress test.
        /// </summary>
        private static readonly TimeSpan SaturationThreshold = TimeSpan.FromSeconds(15);

        private IReadFinishedSignal _signal;

        protected virtual IChannelHandler GetEncoder()
        {
            return new LengthFieldPrepender(4, false);
        }

        protected virtual IChannelHandler GetDecoder()
        {
            return new LengthFieldBasedFrameDecoder(Int32.MaxValue, 0, 4, 0, 4);
        }

        [PerfSetup]
        public void SetUp(BenchmarkContext context)
        {
            ClientGroup = new MultithreadEventLoopGroup(Environment.ProcessorCount/2);
            ServerGroup = new MultithreadEventLoopGroup(1);
            WorkerGroup = new MultithreadEventLoopGroup(Environment.ProcessorCount/2);

            _shutdownBenchmark = new CancellationTokenSource();
            _clientChannels = new ConcurrentBag<IChannel>();

            _inboundThroughputCounter = context.GetCounter(InboundThroughputCounterName);
            _outboundThroughputCounter = context.GetCounter(OutboundThroughputCounterName);
            _clientConnectedCounter = context.GetCounter(ClientConnectCounterName);
            _errorCounter = context.GetCounter(ErrorCounterName);

            _signal = new ManualResetEventSlimReadFinishedSignal(ResetEvent);

            var sb = new ServerBootstrap().Group(ServerGroup, WorkerGroup).Channel<TcpServerSocketChannel>()
                .ChildOption(ChannelOption.TcpNodelay, true)
                .ChildHandler(new ActionChannelInitializer<TcpSocketChannel>(channel =>
                {
                    channel.Pipeline.AddLast(GetEncoder())
                        .AddLast(GetDecoder())
                        .AddLast(new IntCodec(true))
                        .AddLast(new CounterHandlerInbound(_inboundThroughputCounter))
                        .AddLast(new CounterHandlerOutbound(_outboundThroughputCounter))
                        .AddLast(new ErrorCounterHandler(_errorCounter));
                }));

            ClientBootstrap = new ClientBootstrap().Group(ClientGroup)
                .Option(ChannelOption.TcpNodelay, true)
                .Channel<TcpSocketChannel>().Handler(new ActionChannelInitializer<TcpSocketChannel>(
                channel =>
                {
                    channel.Pipeline.AddLast(GetEncoder())
                    .AddLast(GetDecoder())
                    .AddLast(new IntCodec(true))
                    .AddLast(new CounterHandlerInbound(_inboundThroughputCounter))
                    .AddLast(new CounterHandlerOutbound(_outboundThroughputCounter))
                    .AddLast(new ErrorCounterHandler(_errorCounter));
                }));

            var token = _shutdownBenchmark.Token;
            _eventLoop = () =>
            {
                while (!token.IsCancellationRequested)
                {
                    foreach (var channel in _clientChannels)
                    {
                        // unrolling a loop
                        channel.WriteAsync(ThreadLocalRandom.Current.Next());
                        channel.WriteAsync(ThreadLocalRandom.Current.Next());
                        channel.WriteAsync(ThreadLocalRandom.Current.Next());
                        channel.WriteAsync(ThreadLocalRandom.Current.Next());
                        channel.WriteAsync(ThreadLocalRandom.Current.Next());
                        channel.WriteAsync(ThreadLocalRandom.Current.Next());
                        channel.WriteAsync(ThreadLocalRandom.Current.Next());
                        channel.WriteAsync(ThreadLocalRandom.Current.Next());
                        channel.WriteAsync(ThreadLocalRandom.Current.Next());
                        channel.Flush();
                    }

                    // sleep for a tiny bit, then get going again
                    Thread.Sleep(40);
                }
            };

            // start server
            _serverChannel = sb.BindAsync(TEST_ADDRESS).Result;

            // connect to server with 1 client initially
            _clientChannels.Add(ClientBootstrap.ConnectAsync(_serverChannel.LocalAddress).Result);

        }

        private Action _eventLoop;

        [PerfBenchmark(Description = "Measures how quickly and with how much GC overhead a TcpSocketChannel --> TcpServerSocketChannel connection can decode / encode realistic messages",
            NumberOfIterations = IterationCount, RunMode = RunMode.Iterations)]
        [CounterMeasurement(InboundThroughputCounterName)]
        [CounterMeasurement(OutboundThroughputCounterName)]
        [CounterMeasurement(ClientConnectCounterName)]
        [CounterMeasurement(ErrorCounterName)]
        [GcMeasurement(GcMetric.TotalCollections, GcGeneration.AllGc)]
        [MemoryMeasurement(MemoryMetric.TotalBytesAllocated)]
        public void TcpServerSocketChannel_horizontal_scale_stress_test(BenchmarkContext context)
        {
            _clientConnectedCounter.Increment(); // for the initial client
            var totalRunSeconds = TimeSpan.FromSeconds(ThreadLocalRandom.Current.Next(180, 360)); // 3-6 minutes
            Console.WriteLine("Running benchmark for {0} minutes", totalRunSeconds.TotalMinutes);
            var deadline = new PreciseDeadline(totalRunSeconds);
            var due = DateTime.Now + totalRunSeconds;
            var lastMeasure = due;
            var task = Task.Factory.StartNew(_eventLoop); // start writing
            var runCount = 1;
            while (!deadline.IsOverdue)
            {
                // add a new client
                _clientChannels.Add(ClientBootstrap.ConnectAsync(_serverChannel.LocalAddress).Result);
                _clientConnectedCounter.Increment();
                Thread.Sleep(SleepInterval);
                if (++runCount%10 == 0)
                {
                    Console.WriteLine("{0} minutes remaining [{1} connections active].", (due - DateTime.Now).TotalMinutes, runCount);
                    var saturation = (DateTime.Now - lastMeasure);
                    if (saturation > SaturationThreshold)
                    {
                        Console.WriteLine("Took {0} to create 10 connections; exceeded pre-defined saturation threshold of {1}. Ending stress test.", saturation, SaturationThreshold);
                        break;
                    }
                    lastMeasure = DateTime.Now;
                }
            }
            _shutdownBenchmark.Cancel();
        }


        [PerfCleanup]
        public void TearDown()
        {
            _eventLoop = null;
            var shutdownTasks = new List<Task>();
            foreach (var channel in _clientChannels)
            {
                shutdownTasks.Add(channel.CloseAsync());
            }
            Task.WaitAll(shutdownTasks.ToArray());
            CloseChannel(_serverChannel);
            Task.WaitAll(ClientGroup.ShutdownGracefullyAsync(), ServerGroup.ShutdownGracefullyAsync(), WorkerGroup.ShutdownGracefullyAsync());
        }

        private static void CloseChannel(IChannel cc)
        {
            cc?.CloseAsync().Wait();
        }
    }

Used 4 counters at once there

@tigerclawn82
Copy link
Author

Hi,
Sorry but i might be missing something, there is single perf method in this eg which uses multiple counters. In my case, i have multiple methods with their own counters.

@Aaronontheweb
Copy link
Member

Multiple test methods:

/// <summary>
    ///     Performance specifications for <see cref="ActorPath" />
    /// </summary>
    public class ActorPathSpec
    {
        private const string ParseThroughputCounterName = "ParseOp";
        private const double MinimumAcceptableOperationsPerSecond = 1000000.0d; //million op / second
        private static readonly RootActorPath RootAddress = new RootActorPath(Address.AllSystems);
        private Counter _parseThroughput;

        [PerfSetup]
        public void Setup(BenchmarkContext context)
        {
            _parseThroughput = context.GetCounter(ParseThroughputCounterName);
        }

        [PerfBenchmark(Description = "Tests how quickly ActorPath.Parse can run on a LOCAL actor path",
            RunMode = RunMode.Throughput, NumberOfIterations = 13, RunTimeMilliseconds = 1000,
            TestMode = TestMode.Measurement)]
        [CounterThroughputAssertion(ParseThroughputCounterName, MustBe.GreaterThan, MinimumAcceptableOperationsPerSecond
            )]
        [GcMeasurement(GcMetric.TotalCollections, GcGeneration.AllGc)]
        public void Parse_local_throughput(BenchmarkContext context)
        {
            ActorPath.Parse("akka://Sys/user/foo");
            _parseThroughput.Increment();
        }

        [PerfBenchmark(Description = "Tests how quickly ActorPath.Parse can run on a REMOTE actor path",
            RunMode = RunMode.Throughput, NumberOfIterations = 13, RunTimeMilliseconds = 1000,
            TestMode = TestMode.Measurement)]
        [CounterThroughputAssertion(ParseThroughputCounterName, MustBe.GreaterThan, MinimumAcceptableOperationsPerSecond
            )]
        [GcMeasurement(GcMetric.TotalCollections, GcGeneration.AllGc)]
        public void Parse_remote_throughput(BenchmarkContext context)
        {
            ActorPath.Parse("akka.tcp://Sys@localhost:9091/user/foo");
            _parseThroughput.Increment();
        }

        [PerfBenchmark(Description = "Tests how quickly ActorPath.TryParse can run on a LOCAL actor path",
            RunMode = RunMode.Throughput, NumberOfIterations = 13, RunTimeMilliseconds = 1000,
            TestMode = TestMode.Measurement)]
        [CounterThroughputAssertion(ParseThroughputCounterName, MustBe.GreaterThan, MinimumAcceptableOperationsPerSecond
            )]
        [GcMeasurement(GcMetric.TotalCollections, GcGeneration.AllGc)]
        public void TryParse_local_throughput(BenchmarkContext context)
        {
            ActorPath target;
            ActorPath.TryParse("akka://Sys/user/foo", out target);
            _parseThroughput.Increment();
        }

        [PerfBenchmark(Description = "Tests how quickly ActorPath.TryParse can run on a REMOTE actor path",
            RunMode = RunMode.Throughput, NumberOfIterations = 13, RunTimeMilliseconds = 1000,
            TestMode = TestMode.Measurement)]
        [CounterThroughputAssertion(ParseThroughputCounterName, MustBe.GreaterThan, MinimumAcceptableOperationsPerSecond
            )]
        [GcMeasurement(GcMetric.TotalCollections, GcGeneration.AllGc)]
        public void TryParse_remote_throughput(BenchmarkContext context)
        {
            ActorPath target;
            ActorPath.TryParse("akka.tcp://Sys@localhost:9091/user/foo", out target);
            _parseThroughput.Increment();
        }

        [PerfBenchmark(Description = "Tests how quickly ActorPath.TryParseAddress can run on a LOCAL address",
            RunMode = RunMode.Throughput, NumberOfIterations = 13, RunTimeMilliseconds = 1000,
            TestMode = TestMode.Measurement)]
        [CounterThroughputAssertion(ParseThroughputCounterName, MustBe.GreaterThan, 
            MinimumAcceptableOperationsPerSecond)]
        [GcMeasurement(GcMetric.TotalCollections, GcGeneration.AllGc)]
        public void TryParse_address_local_throughput(BenchmarkContext context)
        {
            Address target;
            ActorPath.TryParseAddress("akka://Sys/user/foo", out target);
            _parseThroughput.Increment();
        }

        [PerfBenchmark(Description = "Tests how quickly ActorPath.TryParseAddress can run on a REMOTE address",
            RunMode = RunMode.Throughput, NumberOfIterations = 13, RunTimeMilliseconds = 1000,
            TestMode = TestMode.Measurement)]
        [CounterThroughputAssertion(ParseThroughputCounterName, MustBe.GreaterThan, MinimumAcceptableOperationsPerSecond
            )]
        [GcMeasurement(GcMetric.TotalCollections, GcGeneration.AllGc)]
        public void TryParse_address_remote_throughput(BenchmarkContext context)
        {
            Address target;
            ActorPath.TryParseAddress("akka.tcp://Sys@locahost:9101/user/foo", out target);
            _parseThroughput.Increment();
        }

        [PerfBenchmark(Description = "Tests how quickly a single ActorPath '/' operation can run",
            RunMode = RunMode.Throughput, NumberOfIterations = 13, RunTimeMilliseconds = 1000,
            TestMode = TestMode.Measurement)]
        [CounterThroughputAssertion(ParseThroughputCounterName, MustBe.GreaterThan, MinimumAcceptableOperationsPerSecond
            )]
        [GcMeasurement(GcMetric.TotalCollections, GcGeneration.AllGc)]
        public void ActorPath1_concatenate_throughput(BenchmarkContext context)
        {
            var newPath = RootAddress/"user";
            _parseThroughput.Increment();
        }

        [PerfBenchmark(
            Description =
                "Tests how quickly a two immediate ActorPath '/' operations can run - much closer to how this method works in the real world",
            RunMode = RunMode.Throughput, NumberOfIterations = 13, RunTimeMilliseconds = 1000,
            TestMode = TestMode.Measurement)]
        [CounterThroughputAssertion(ParseThroughputCounterName, MustBe.GreaterThan, MinimumAcceptableOperationsPerSecond
            )]
        [GcMeasurement(GcMetric.TotalCollections, GcGeneration.AllGc)]
        public void ActorPath2_concatenate_throughput(BenchmarkContext context)
        {
            var newPath = RootAddress/"user"/"foo";
            _parseThroughput.Increment();
        }

        [PerfBenchmark(Description = "Tests how much memory 100,000 ActorPath instances consume",
            RunMode = RunMode.Iterations, NumberOfIterations = 13, RunTimeMilliseconds = 1000,
            TestMode = TestMode.Measurement)]
        [CounterMeasurement(ParseThroughputCounterName)]
        [MemoryMeasurement(MemoryMetric.TotalBytesAllocated)]
        [GcMeasurement(GcMetric.TotalCollections, GcGeneration.AllGc)]
        public void Memory_footprint(BenchmarkContext context)
        {
            var actorPaths = new ActorPath[100000];
            for (var i = 0; i < 100000;)
            {
                actorPaths[i] = new RootActorPath(Address.AllSystems);
                ++i;
                _parseThroughput.Increment();
            }
        }
    }

@Aaronontheweb
Copy link
Member

Sorry, took me a bit longer to grab the second one - had to open a different project up :p

@tigerclawn82
Copy link
Author

Hi,
In this eg also, there are multiple perf methods but uses same counter. In my eg. there are multiple perf methods and have its own counter.

[PerfBenchmark(Description = "Test to ensure that minimal Througput of __.Val is sufficient",
        NumberOfIterations = 3, RunMode = RunMode.Throughput,
        RunTimeMilliseconds = 1000, TestMode = TestMode.Test)]
        [CounterThroughputAssertion("Counter_Logger_Val", MustBe.GreaterThan, 1000000d)]
        [MemoryAssertion(MemoryMetric.TotalBytesAllocated, MustBe.LessThanOrEqualTo, ByteConstants.SixteenKb * 1000)]
        [GcTotalAssertion(GcMetric.TotalCollections, GcGeneration.Gen2, MustBe.ExactlyEqualTo, 0.0d)]
        public void Perf_Logger_Val(BenchmarkContext context)
        {
            Assert.Equal(__.Val(Logger.Level.NotSpecified), "NotSpecified");
            string[] values = { "", null, "A" };
            Assert.Equal(__.Val(values), "A");
            Assert.Equal(__.Val(false, values), "");
            Counter_Logger_Val.Increment();
        }

used Counter_Logger_Val

[PerfBenchmark(Description = "Test to ensure that minimal Througput of __.DB is sufficient",
        NumberOfIterations = 3, RunMode = RunMode.Throughput,
        RunTimeMilliseconds = 1000, TestMode = TestMode.Test)]
        [CounterThroughputAssertion("Counter_Logger_DB", MustBe.GreaterThan, 1000000d)]
        [MemoryAssertion(MemoryMetric.TotalBytesAllocated, MustBe.LessThanOrEqualTo, ByteConstants.SixteenKb * 1000)]
        [GcTotalAssertion(GcMetric.TotalCollections, GcGeneration.Gen2, MustBe.ExactlyEqualTo, 0.0d)]
        public void Test_Logger_DB(BenchmarkContext context)
        {
            Assert.Equal(__.DB("DB", "USER", "PASSWORD"), "USER/********@DB");
            typeof(Options).GetField("_ShowPassword", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static).SetValue(null, 1);
            Assert.Equal(__.DB("DB", "USER", "PASSWORD"), "USER/PASSWORD@DB");
            typeof(Options).GetField("_ShowPassword", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static).SetValue(null, 0);
            Counter_Logger_DB.Increment();
        }

used Counter_Logger_DB

@Aaronontheweb
Copy link
Member

@tigerclawn82, ah, in that case you just need to make sure that you assign Counter_Logger_Db to the correct Counter instance. Might be easier to break those up into separate classes.

@tigerclawn82
Copy link
Author

Hi,
I am using correct counters but may be something missing. Test_Logger_DB has [CounterThroughputAssertion("Counter_Logger_DB", MustBe.GreaterThan, 1000000d)] and i used Counter_Logger_DB which i extracted in

[PerfSetup]
        public void Setup(BenchmarkContext context)
        {
            Counter_Logger_Val = context.GetCounter("Counter_Logger_Val");
            Counter_Logger_DB = context.GetCounter("Counter_Logger_DB");
        }

Yeah, right now i have created separated classes per method but it seems overkill. But, thanks for your instant support 👍

@Aaronontheweb
Copy link
Member

@tigerclawn82 You're welcome! In a future release we're going to be adding something similar to XUnit Theories which might be able to help reduce the amount of code you have to write to do this.

@tigerclawn82
Copy link
Author

I will try to directly get counters in perf methods rather [PerfSetup]. I am gonna keep this issue open.
That would be great, this is really helpful library and that will make it way better.
Thanks

@tigerclawn82
Copy link
Author

Hi, tried getting counter directly via context.GetCounter() and it seems to be working fine. But in documentation, it is advised to get counters in [PerfSetup] due to performance penalty. Might be there is some kinda issue in the way counters are extracted per class.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants