Last active
January 28, 2021 20:03
-
-
Save terite/3506da1ac8064cdb1f8f11e81661a59f to your computer and use it in GitHub Desktop.
SharpPcap Span<T> benchmark
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using BenchmarkDotNet.Running; | |
using BenchmarkDotNet.Attributes; | |
using System; | |
using SharpPcap.LibPcap; | |
using SharpPcap; | |
namespace SomeProject.Benchmarks | |
{ | |
public class Program | |
{ | |
static readonly bool BENCHMARK = true; | |
public static void Main(string[] args) | |
{ | |
if (BENCHMARK) | |
{ | |
var summary = BenchmarkRunner.Run<WholeFileBenchmark>(); | |
Console.WriteLine(summary); | |
} | |
else | |
{ | |
var benchmark = new WholeFileBenchmark(); | |
var alloc = benchmark.ReadFileAlloc(); | |
Console.WriteLine("Alloc:"); | |
Console.WriteLine($"Read {alloc.packetsRead} packets"); | |
Console.WriteLine($"Read {alloc.bytesRead} bytes"); | |
var noAlloc = benchmark.ReadFileNoAlloc(); | |
Console.WriteLine("\nNo Alloc:"); | |
Console.WriteLine($"Read {noAlloc.packetsRead} packets"); | |
Console.WriteLine($"Read {noAlloc.bytesRead} bytes"); | |
} | |
} | |
} | |
[MemoryDiagnoser] | |
public class WholeFileBenchmark | |
{ | |
static readonly string filename = @"<your-file-path-here>"; | |
public WholeFileBenchmark() | |
{ | |
if (!System.IO.File.Exists(filename)) | |
throw new Exception($"File does not exist {filename}"); | |
} | |
[Benchmark] | |
public (uint packetsRead, uint bytesRead) ReadFileAlloc() | |
{ | |
var device = new NoAllocCaptureFileReaderDevice(filename); | |
device.Open(); | |
if (!device.Opened) throw new Exception("Device not opened?"); | |
uint packetsRead = 0; | |
uint bytesRead = 0; | |
RawCapture rawCapture; | |
while ((rawCapture = device.GetNextPacket()) != null) { | |
++packetsRead; | |
bytesRead += (uint) rawCapture.Data.Length; | |
} | |
return (packetsRead, bytesRead); | |
} | |
[Benchmark] | |
public (uint packetsRead, uint bytesRead) ReadFileNoAlloc() | |
{ | |
var device = new NoAllocCaptureFileReaderDevice(filename); | |
device.Open(); | |
if (!device.Opened) throw new Exception("Device not opened?"); | |
uint packetsRead = 0; | |
uint bytesRead = 0; | |
while (device.TryGetNextPacketNoAlloc(out PcapHeader pcapHeader, out Span<byte> rawData)) | |
{ | |
++packetsRead; | |
bytesRead += (uint) rawData.Length; | |
} | |
return (packetsRead, bytesRead); | |
} | |
} | |
public class NoAllocCaptureFileReaderDevice : CaptureFileReaderDevice | |
{ | |
public NoAllocCaptureFileReaderDevice(string fileName) : base(fileName) { } | |
public unsafe bool TryGetNextPacketNoAlloc(out PcapHeader header, out Span<byte> data) | |
{ | |
IntPtr headerPtr = IntPtr.Zero; | |
IntPtr dataPtr = IntPtr.Zero; | |
int res = GetNextPacketPointers(ref headerPtr, ref dataPtr); | |
if (res > 0) | |
{ | |
header = PcapHeader.FromPointer(headerPtr); | |
data = new Span<byte>(dataPtr.ToPointer(), (int)header.CaptureLength); | |
return true; | |
} | |
else | |
{ | |
header = default; | |
data = Span<byte>.Empty; | |
return false; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment