Skip to content

jstedfast/MimeParserBenchmark

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MimeParserBenchmark

This project benchmarks various .NET MIME parsers for comparison purposes.

Package Versions

Package Version
MimeKit 4.12.0
LimiLabs' Mail.dll 3.0.25121.1408
Mime4Net 1.8.1
AE.Net.Mail 1.7.10
MailSystem.NET 2.0.1
OpenPOP.NET 2.0.6.1120

Runtime

BenchmarkDotNet v0.14.0, Windows 11 (10.0.26100.3775)
Intel Core i7-9700 CPU 3.00GHz, 1 CPU, 8 logical and 8 physical cores
  [Host]     : .NET Framework 4.8.1 (4.8.9290.0), X64 RyuJIT VectorSize=256
  DefaultJob : .NET Framework 4.8.1 (4.8.9290.0), X64 RyuJIT VectorSize=256

Results

HeavyHeaderEmailBenchmark

In this benchmark, each library is used to parse an in-memory email message that is almost all headers 1,000 times.

Method Mean Error StdDev
MimeKit 30.28 ms 0.229 ms 0.215 ms
MimeKitPersistent 30.53 ms 0.546 ms 0.484 ms
LimiLabs 729.34 ms 7.569 ms 6.321 ms
Mime4Net 573.89 ms 9.861 ms 10.551 ms
OpenPOP 399.10 ms 7.696 ms 8.554 ms
AENetMail 2,912.24 ms 57.274 ms 70.338 ms
MailSystemNET 1,954.23 ms 25.525 ms 22.627 ms

JwzMboxBenchmark

In this benchmark, each library is used to parse the jwz.mbox Unix mbox spool from disk 10 times.

Method Mean Error StdDev
MimeKit 177.1 ms 2.52 ms 2.36 ms
MimeKitPersistent 163.7 ms 2.92 ms 4.64 ms
LimiLabs 1,166.2 ms 23.01 ms 21.52 ms

StarTrekEmailBenchmark

In this benchmark, each library is used to parse startrek.eml from disk 1,000 times.

Method Mean Error StdDev
MimeKit 216.6 ms 4.33 ms 5.48 ms
MimeKitPersistent 195.7 ms 3.91 ms 5.48 ms
LimiLabs 5,776.4 ms 110.47 ms 118.20 ms
Mime4Net 11,114.1 ms 85.75 ms 76.01 ms
OpenPOP NA NA NA
AENetMail 4,018.5 ms 26.65 ms 20.80 ms
MailSystemNET 9,528.9 ms 127.01 ms 99.16 ms

Notes:

  • MailSystem.NET's parser only supports parsing from byte[] or MemoryStream, so in this test, MailSystem.NET is allowed to "cheat" by parsing an in-memory version of the message instead of being forced to parse from disk in each iteration.
  • OpenPOP.NET fails to parse this message with the following exception:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.ArgumentException: Media Type must be in the format type "/" subtype
Parameter name: mediaType
   at OpenPop.Mime.Header.HeaderFieldParser.cleanMediaType(String mediaType)
   at OpenPop.Mime.Header.HeaderFieldParser.ParseContentType(String headerValue)
   at OpenPop.Mime.Header.MessageHeader.ParseHeader(String headerName, String headerValue)
   at OpenPop.Mime.Header.MessageHeader.ParseHeaders(NameValueCollection headers)
   at OpenPop.Mime.Header.HeaderExtractor.ExtractHeadersAndBody(Byte[] fullRawMessage, MessageHeader& headers, Byte[]& body, IParsingErrorHandler parsingErrorHandler)
   at OpenPop.Mime.MessagePart.ParseMultiPartBody(Byte[] rawBody)
   at OpenPop.Mime.MessagePart.ParseMultiPartBody(Byte[] rawBody)
   at OpenPop.Mime.Message.Load(Stream messageStream, IParsingErrorHandler parsingErrorHandler)
   at Benchmarks.StarTrekEmailBenchmarks.OpenPOP()
   at BenchmarkDotNet.Autogenerated.Runnable_14.WorkloadActionNoUnroll(Int64 invokeCount)
   at BenchmarkDotNet.Engines.Engine.RunIteration(IterationData data)
   at BenchmarkDotNet.Engines.EngineFactory.Jit(Engine engine, Int32 jitIndex, Int32 invokeCount, Int32 unrollFactor)
   at BenchmarkDotNet.Engines.EngineFactory.CreateReadyToRun(EngineParameters engineParameters)
   at BenchmarkDotNet.Autogenerated.Runnable_14.Run(IHost host, String benchmarkName)
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
   at BenchmarkDotNet.Autogenerated.UniqueProgramName.AfterAssemblyLoadingAttached(String[] args)

Xamarin3EmailBenchmark

In this benchmark, each library is used to parse xamarin3.eml from disk 1,000 times.

Method Mean Error StdDev Median
MimeKit 1.693 s 0.0316 s 0.0400 s 1.679 s
MimeKitPersistent 1.314 s 0.0201 s 0.0188 s 1.312 s
LimiLabs 14.392 s 0.1196 s 0.1060 s 14.362 s
Mime4Net 90.029 s 1.0404 s 0.9732 s 90.027 s
OpenPOP 78.548 s 1.0670 s 0.9981 s 78.792 s
AENetMail 31.338 s 0.5670 s 0.6529 s 31.322 s
MailSystemNET 54.039 s 1.0752 s 3.1363 s 52.791 s

Notes:

  • MailSystem.NET's parser only supports parsing from byte[] or MemoryStream, so in this test, MailSystem.NET is allowed to "cheat" by parsing an in-memory version of the message instead of being forced to parse from disk in each iteration.

Conclusions

Yea. No contest. MimeKit mops the floor with all of the other parsers out there.

How does your MIME parser compare?

About

Benchmark for popular MIME parsers for .NET

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •  

Languages