From 05ba1c9d52c056e33b4121ea55812ae596016ea3 Mon Sep 17 00:00:00 2001 From: Kevin Laeufer Date: Wed, 8 Jul 2020 11:46:51 -0700 Subject: ir: add faster serializer (#1694) This Serializer which is implemented external to the IR node definition uses a StringBuilder to achieve about a 1.7x performance improvement when serializing. Eventually, all implementations of the `serialize` methd should be replaced with a call to `Serializer.serialize`. However, for this PR we keep the old code in place in order to allow for easy regression testing with the benchmark JAR like this: > java -cp utils/bin/firrtl-benchmark.jar \ firrtl.benchmark.hot.SerializationBenchmark \ ~/benchmarks/medium.pb 2 5 test Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>--- .../benchmark/hot/SerializationBenchmark.scala | 40 ++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 benchmark/src/main/scala/firrtl/benchmark/hot/SerializationBenchmark.scala (limited to 'benchmark/src') diff --git a/benchmark/src/main/scala/firrtl/benchmark/hot/SerializationBenchmark.scala b/benchmark/src/main/scala/firrtl/benchmark/hot/SerializationBenchmark.scala new file mode 100644 index 00000000..e6ef04ec --- /dev/null +++ b/benchmark/src/main/scala/firrtl/benchmark/hot/SerializationBenchmark.scala @@ -0,0 +1,40 @@ +// See LICENSE for license details. +package firrtl.benchmark.hot + +import firrtl.benchmark.util._ +import firrtl.ir.Serializer + +object SerializationBenchmark extends App { + val inputFile = args(0) + val warmup = args(1).toInt + val runs = args(2).toInt + val select = if(args.length > 3) args(3) else "o" + + val input = filenameToCircuit(inputFile) + + if(select == "n") { + println("Benchmarking new Serializer.serialize") + firrtl.benchmark.hot.util.benchmark(warmup, runs)(Serializer.serialize(input)) + } else if(select == "o") { + println("Benchmarking legacy serialization") + firrtl.benchmark.hot.util.benchmark(warmup, runs)(input.serialize) + } else if(select.startsWith("test")) { + println("Testing the new serialization against the old one") + val o = input.serialize.split('\n').filterNot(_.trim.isEmpty) + val n = Serializer.serialize(input).split('\n').filterNot(_.trim.isEmpty) + val silent = select.endsWith("silent") + + println(s"Old lines: ${o.length}") + println(s"New lines: ${n.length}") + o.zip(n).zipWithIndex.foreach { case ((ol, nl), ii) => + if(ol != nl) { + println(s"❌@$ii OLD: |$ol|") + println(s"❌@$ii NEW: |$nl|") + throw new RuntimeException() + } else if(!silent) { + println(s"✅ |$ol") + } + } + + } +} -- cgit v1.2.3