anchor.diff:      pathTestCases                   dumper
   #if !DEBUG
       performanceTestCases            dumper
  -    performanceJsonNetTestCases     dumper
  -    performanceFSharpDataTestCases  dumper
   #endif
   
     with
  
positive.code: 
      sw.Stop ()
  
      sw.ElapsedMilliseconds, result
  
    for positive, name, testCase in testCases do
      dumper <| sprintf "---==> %s <==---" category
      dumper name
      dumper (if positive then "positive" else "negative")
      dumper testCase
  
      let reference , _ = timeIt iterations (fun _ -> referenceParser testCase)
      let actual    , _ = timeIt iterations (fun _ -> parse false testCase)
  
      let actual_ratio  = float reference / max (float actual) 1.
  
      let ref           = float reference / float iterations
      let act           = float actual / float iterations
  
      check_lt expected_ratio     actual_ratio            name
      check_gt ref                (expected_ratio * act)  name
  
      dumper <| sprintf "Iterations: %d, reference: %d ms, actual: %d ms" iterations reference actual
  // ----------------------------------------------------------------------------------------------
  
  // ----------------------------------------------------------------------------------------------
  let performanceRatio v = max 1.0 v
  // ----------------------------------------------------------------------------------------------
  
  // ----------------------------------------------------------------------------------------------
  let performanceTestCases (dumper : string -> unit) =
    let testCases =
      Array.concat [|positiveTestCases; negativeTestCases; sampleTestCases; generatedTestCases |]
      |> Array.filter filterForPerformance
  
    infof "Running %d performance testcases (REFERENCE)..." testCases.Length
  
    runPerformanceTestCases
      "PERFORMANCE TEST (REFERENCE)"
      ReferenceJsonModule.parse
      200
      (performanceRatio 4.0)
      testCases
      dumper
  // ----------------------------------------------------------------------------------------------
  
  // ----------------------------------------------------------------------------------------------
  let performanceJsonNetTestCases (dumper : string -> unit) =
    let testCases =
      Array.concat [|positiveTestCases; negativeTestCases; sampleTestCases; generatedTestCases |]
      |> Array.filter filterForJsonNet
      |> Array.filter filterForPerformance
  
    infof "Running %d performance testcases (JSON.NET)..." testCases.Length
  
    runPerformanceTestCases
      "PERFORMANCE TEST (JSON.NET)"
      MiniJson.Tests.JsonNet.parse
      1000
      (performanceRatio 1.1)
      testCases
      dumper
  // ----------------------------------------------------------------------------------------------
  
  // ----------------------------------------------------------------------------------------------
  let performanceFSharpDataTestCases (dumper : string -> unit) =
    let testCases =
      Array.concat [|positiveTestCases; negativeTestCases; sampleTestCases; generatedTestCases |]
      |> Array.filter filterForFSharpData
      |> Array.filter filterForPerformance
  
    infof "Running %d performance testcases (FSHARP.DATA)..." testCases.Length
  
    runPerformanceTestCases
      "PERFORMANCE TEST (FSHARP.DATA)"
      MiniJson.Tests.FSharpData.dummyParse  // As we don't want to pay overhead of data conversion
      1000
      (performanceRatio 1.5)
      testCases
      dumper
  // ----------------------------------------------------------------------------------------------
  
  // ----------------------------------------------------------------------------------------------
  
negative.code: // ----------------------------------------------------------------------------------------------
  
  // ----------------------------------------------------------------------------------------------
  type PerformanceData = string*int*int*int*int*int64
  
  let collectPerformanceData
    (category       : string                  )
    (parser         : string -> ParseResult   )
    (iterations     : int                     )
    (testCases      : (bool*string*string) [] )
    (dumper         : string -> unit          ) : PerformanceData [] =
  
    infof "Collecting performance data for %d testcases (%s)..." testCases.Length category
  
    let sw = Stopwatch ()
  
    let timeIt n (a : unit -> 'T) : int64*int*int*int*'T =
      sw.Reset ()
  
      let result = a ()
  
      GC.Collect (2, GCCollectionMode.Forced, true)
  
      let b0  = GC.CollectionCount 0
      let b1  = GC.CollectionCount 1
      let b2  = GC.CollectionCount 2
  
      sw.Start ()
  
  