[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [stem/master] Benchmarks for our descriptor parsing libraries
commit 6dd30e5beda287cd02fabd257028e1711aa63f99
Author: Damian Johnson <atagar@xxxxxxxxxxxxxx>
Date: Sat Jan 16 19:18:25 2016 -0800
Benchmarks for our descriptor parsing libraries
Karsten, Philipp, and I have been discussing library benchmarks on tor-dev@.
Adding the findings...
https://lists.torproject.org/pipermail/tor-dev/2016-January/010230.html
---
docs/_static/example/benchmark_metrics_lib.java | 302 ++++++++++++++++++++
.../benchmark_server_descriptor_metrics_lib.java | 49 ++++
.../example/benchmark_server_descriptor_stem.py | 21 ++
.../example/benchmark_server_descriptor_zoossh.go | 68 +++++
docs/_static/example/benchmark_stem.py | 81 ++++++
docs/_static/example/benchmark_zoossh.go | 120 ++++++++
docs/tutorials/mirror_mirror_on_the_wall.rst | 96 +++++--
7 files changed, 712 insertions(+), 25 deletions(-)
diff --git a/docs/_static/example/benchmark_metrics_lib.java b/docs/_static/example/benchmark_metrics_lib.java
new file mode 100644
index 0000000..63b5e4b
--- /dev/null
+++ b/docs/_static/example/benchmark_metrics_lib.java
@@ -0,0 +1,302 @@
+/* Copyright 2016 The Tor Project
+ * See LICENSE for licensing information */
+package org.torproject.descriptor;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.SortedMap;
+
+public class MeasurePerformance {
+
+ /* Check if all necessary files are available and then measure
+ * performance of some more or less common use cases. */
+ public static void main(String[] args) {
+ if (!filesAvailable()) {
+ return;
+ }
+ /*measureListOutdatedRelays(null);
+ pause();*/
+ measureAverageAdvertisedBandwidth(new File(resDir, resPaths[0]));
+ pause();
+ measureAverageAdvertisedBandwidth(new File(resDir, resPaths[1]));
+ pause();
+ measureAverageAdvertisedBandwidth(new File(resDir, resPaths[2]));
+ pause();
+ /*measureFractionRelaysExit80ServerDescriptors(null);
+ pause();
+ measureSumOfWrittenAndReadBytes(null);
+ pause();*/
+ measureCountriesV3Requests(new File(resDir, resPaths[3]));
+ pause();
+ measureCountriesV3Requests(new File(resDir, resPaths[4]));
+ pause();
+ measureAverageRelaysExit(new File(resDir, resPaths[5]));
+ pause();
+ measureAverageRelaysExit(new File(resDir, resPaths[6]));
+ pause();
+ measureAverageRelaysExit(new File(resDir, resPaths[7]));
+ /*pause();
+ measureVotesByBandwidthAuthorities(null);
+ pause();
+ measureExtendedFamilies(null);
+ pause();*/
+ measureFractionRelaysExit80Microdescriptors(
+ new File(resDir, resPaths[8]));
+ measureFractionRelaysExit80Microdescriptors(
+ new File(resDir, resPaths[9]));
+ }
+
+ private static File resDir = new File("res");
+ private static String[] resPaths = new String[] {
+ "archive/relay-descriptors/server-descriptors/"
+ + "server-descriptors-2015-11.tar.xz",
+ "archive/relay-descriptors/server-descriptors/"
+ + "server-descriptors-2015-11.tar",
+ "archive/relay-descriptors/server-descriptors/"
+ + "server-descriptors-2015-11",
+ "archive/relay-descriptors/extra-infos/extra-infos-2015-11.tar.xz",
+ "archive/relay-descriptors/extra-infos/extra-infos-2015-11.tar",
+ "archive/relay-descriptors/consensuses/consensuses-2015-11.tar.xz",
+ "archive/relay-descriptors/consensuses/consensuses-2015-11.tar",
+ "archive/relay-descriptors/consensuses/consensuses-2015-11",
+ "archive/relay-descriptors/microdescs/"
+ + "microdescs-2015-11-micro.tar.xz",
+ "archive/relay-descriptors/microdescs/microdescs-2015-11-micro.tar"
+ };
+
+ private static boolean filesAvailable() {
+ if (!resDir.exists() || !resDir.isDirectory()) {
+ return false;
+ }
+ for (String resPath : resPaths) {
+ if (!(new File(resDir, resPath).exists())) {
+ System.err.println(resPath);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private static void pause() {
+ try {
+ Thread.sleep(15L * 1000L);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static void measureListOutdatedRelays(File tarballFile) {
+
+ }
+
+ private static void measureAverageAdvertisedBandwidth(
+ File tarballFileOrDirectory) {
+ System.out.println("Starting measureAverageAdvertisedBandwidth");
+ long startedMillis = System.currentTimeMillis();
+ long sumAdvertisedBandwidth = 0, countedServerDescriptors = 0;
+ DescriptorReader descriptorReader =
+ DescriptorSourceFactory.createDescriptorReader();
+ descriptorReader.addTarball(tarballFileOrDirectory);
+ descriptorReader.addDirectory(tarballFileOrDirectory);
+ Iterator<DescriptorFile> descriptorFiles =
+ descriptorReader.readDescriptors();
+ while (descriptorFiles.hasNext()) {
+ DescriptorFile descriptorFile = descriptorFiles.next();
+ for (Descriptor descriptor : descriptorFile.getDescriptors()) {
+ if (!(descriptor instanceof ServerDescriptor)) {
+ continue;
+ }
+ ServerDescriptor serverDescriptor = (ServerDescriptor) descriptor;
+ sumAdvertisedBandwidth += (long) Math.min(Math.min(
+ serverDescriptor.getBandwidthRate(),
+ serverDescriptor.getBandwidthBurst()),
+ serverDescriptor.getBandwidthObserved());
+ countedServerDescriptors++;
+ }
+ }
+ long endedMillis = System.currentTimeMillis();
+ System.out.println("Ending measureAverageAdvertisedBandwidth");
+ System.out.printf("Total time: %d millis%n",
+ endedMillis - startedMillis);
+ System.out.printf("Processed server descriptors: %d%n",
+ countedServerDescriptors);
+ System.out.printf("Average advertised bandwidth: %d%n",
+ sumAdvertisedBandwidth / countedServerDescriptors);
+ System.out.printf("Time per server descriptor: %.6f millis%n",
+ ((double) (endedMillis - startedMillis))
+ / ((double) countedServerDescriptors));
+ }
+
+ private static void measureFractionRelaysExit80ServerDescriptors(
+ File tarballFile) {
+
+ }
+
+ private static void measureSumOfWrittenAndReadBytes(File tarballFile) {
+
+ }
+
+ private static void measureCountriesV3Requests(File tarballFile) {
+ System.out.println("Starting measureCountriesV3Requests");
+ long startedMillis = System.currentTimeMillis();
+ Set<String> countries = new HashSet<>();
+ long countedExtraInfoDescriptors = 0;
+ DescriptorReader descriptorReader =
+ DescriptorSourceFactory.createDescriptorReader();
+ descriptorReader.addTarball(tarballFile);
+ Iterator<DescriptorFile> descriptorFiles =
+ descriptorReader.readDescriptors();
+ while (descriptorFiles.hasNext()) {
+ DescriptorFile descriptorFile = descriptorFiles.next();
+ for (Descriptor descriptor : descriptorFile.getDescriptors()) {
+ if (!(descriptor instanceof ExtraInfoDescriptor)) {
+ continue;
+ }
+ ExtraInfoDescriptor extraInfoDescriptor =
+ (ExtraInfoDescriptor) descriptor;
+ SortedMap<String, Integer> dirreqV3Reqs =
+ extraInfoDescriptor.getDirreqV3Reqs();
+ if (dirreqV3Reqs != null) {
+ countries.addAll(dirreqV3Reqs.keySet());
+ }
+ countedExtraInfoDescriptors++;
+ }
+ }
+ long endedMillis = System.currentTimeMillis();
+ System.out.println("Ending measureCountriesV3Requests");
+ System.out.printf("Total time: %d millis%n",
+ endedMillis - startedMillis);
+ System.out.printf("Processed extra-info descriptors: %d%n",
+ countedExtraInfoDescriptors);
+ System.out.printf("Number of countries: %d%n",
+ countries.size());
+ System.out.printf("Time per extra-info descriptor: %.6f millis%n",
+ ((double) (endedMillis - startedMillis))
+ / ((double) countedExtraInfoDescriptors));
+ }
+
+ private static void measureAverageRelaysExit(
+ File tarballFileOrDirectory) {
+ System.out.println("Starting measureAverageRelaysExit");
+ long startedMillis = System.currentTimeMillis();
+ long totalRelaysWithExitFlag = 0L, totalRelays = 0L,
+ countedConsensuses = 0L;
+ DescriptorReader descriptorReader =
+ DescriptorSourceFactory.createDescriptorReader();
+ descriptorReader.addTarball(tarballFileOrDirectory);
+ descriptorReader.addDirectory(tarballFileOrDirectory);
+ Iterator<DescriptorFile> descriptorFiles =
+ descriptorReader.readDescriptors();
+ while (descriptorFiles.hasNext()) {
+ DescriptorFile descriptorFile = descriptorFiles.next();
+ for (Descriptor descriptor : descriptorFile.getDescriptors()) {
+ if (!(descriptor instanceof RelayNetworkStatusConsensus)) {
+ continue;
+ }
+ RelayNetworkStatusConsensus consensus =
+ (RelayNetworkStatusConsensus) descriptor;
+ for (NetworkStatusEntry entry :
+ consensus.getStatusEntries().values()) {
+ if (entry.getFlags().contains("Exit")) {
+ totalRelaysWithExitFlag++;
+ }
+ totalRelays++;
+ }
+ countedConsensuses++;
+ }
+ }
+ long endedMillis = System.currentTimeMillis();
+ System.out.println("Ending measureAverageRelaysExit");
+ System.out.printf("Total time: %d millis%n",
+ endedMillis - startedMillis);
+ System.out.printf("Processed consensuses: %d%n", countedConsensuses);
+ System.out.printf("Total number of status entries: %d%n",
+ totalRelays);
+ System.out.printf("Total number of status entries with Exit flag: "
+ + "%d%n", totalRelaysWithExitFlag);
+ System.out.printf("Average number of relays with Exit Flag: %.2f%n",
+ (double) totalRelaysWithExitFlag / (double) totalRelays);
+ System.out.printf("Time per consensus: %.6f millis%n",
+ ((double) (endedMillis - startedMillis))
+ / ((double) countedConsensuses));
+ }
+
+ private static void measureVotesByBandwidthAuthorities(
+ File tarballFile) {
+
+ }
+
+ private static void measureExtendedFamilies(File tarballFile) {
+
+ }
+
+ private static void measureFractionRelaysExit80Microdescriptors(
+ File tarballFile) {
+ System.out.println("Starting "
+ + "measureFractionRelaysExit80Microdescriptors");
+ long startedMillis = System.currentTimeMillis();
+ long totalRelaysWithExitFlag = 0L, countedMicrodescriptors = 0L;
+ DescriptorReader descriptorReader =
+ DescriptorSourceFactory.createDescriptorReader();
+ descriptorReader.addTarball(tarballFile);
+ Iterator<DescriptorFile> descriptorFiles =
+ descriptorReader.readDescriptors();
+ while (descriptorFiles.hasNext()) {
+ DescriptorFile descriptorFile = descriptorFiles.next();
+ for (Descriptor descriptor : descriptorFile.getDescriptors()) {
+ if (!(descriptor instanceof Microdescriptor)) {
+ continue;
+ }
+ countedMicrodescriptors++;
+ Microdescriptor microdescriptor =
+ (Microdescriptor) descriptor;
+ String defaultPolicy = microdescriptor.getDefaultPolicy();
+ if (defaultPolicy == null) {
+ continue;
+ }
+ boolean accept = "accept".equals(
+ microdescriptor.getDefaultPolicy());
+ for (String ports : microdescriptor.getPortList().split(",")) {
+ if (ports.contains("-")) {
+ String[] parts = ports.split("-");
+ int from = Integer.parseInt(parts[0]);
+ int to = Integer.parseInt(parts[1]);
+ if (from <= 80 && to >= 80) {
+ if (accept) {
+ totalRelaysWithExitFlag++;
+ }
+ } else if (to > 80) {
+ if (!accept) {
+ totalRelaysWithExitFlag++;
+ }
+ break;
+ }
+ } else if ("80".equals(ports)) {
+ if (accept) {
+ totalRelaysWithExitFlag++;
+ }
+ break;
+ }
+ }
+ }
+ }
+ long endedMillis = System.currentTimeMillis();
+ System.out.println("Ending "
+ + "measureFractionRelaysExit80Microdescriptors");
+ System.out.printf("Total time: %d millis%n",
+ endedMillis - startedMillis);
+ System.out.printf("Processed microdescriptors: %d%n",
+ countedMicrodescriptors);
+ System.out.printf("Total number of microdescriptors that exit to 80: "
+ + "%d%n", totalRelaysWithExitFlag);
+ System.out.printf("Average number of relays that exit to 80: %.2f%n",
+ (double) totalRelaysWithExitFlag
+ / (double) countedMicrodescriptors);
+ System.out.printf("Time per microdescriptor: %.6f millis%n",
+ ((double) (endedMillis - startedMillis))
+ / ((double) countedMicrodescriptors));
+ }
+}
+
diff --git a/docs/_static/example/benchmark_server_descriptor_metrics_lib.java b/docs/_static/example/benchmark_server_descriptor_metrics_lib.java
new file mode 100644
index 0000000..efb8634
--- /dev/null
+++ b/docs/_static/example/benchmark_server_descriptor_metrics_lib.java
@@ -0,0 +1,49 @@
+package org.torproject.descriptor;
+
+import java.io.File;
+import java.util.Iterator;
+import org.torproject.descriptor.DescriptorSourceFactory;
+
+public class MeasurePerformance {
+ public static void main(String[] args) {
+ measureAverageAdvertisedBandwidth(new File("server-descriptors-2015-11.tar"));
+ }
+
+ private static void measureAverageAdvertisedBandwidth(
+ File tarballFileOrDirectory) {
+ System.out.println("Starting measureAverageAdvertisedBandwidth");
+ long startedMillis = System.currentTimeMillis();
+ long sumAdvertisedBandwidth = 0, countedServerDescriptors = 0;
+ DescriptorReader descriptorReader =
+ DescriptorSourceFactory.createDescriptorReader();
+ descriptorReader.addTarball(tarballFileOrDirectory);
+ descriptorReader.addDirectory(tarballFileOrDirectory);
+ Iterator<DescriptorFile> descriptorFiles =
+ descriptorReader.readDescriptors();
+ while (descriptorFiles.hasNext()) {
+ DescriptorFile descriptorFile = descriptorFiles.next();
+ for (Descriptor descriptor : descriptorFile.getDescriptors()) {
+ if (!(descriptor instanceof ServerDescriptor)) {
+ continue;
+ }
+ ServerDescriptor serverDescriptor = (ServerDescriptor) descriptor;
+ sumAdvertisedBandwidth += (long) Math.min(Math.min(
+ serverDescriptor.getBandwidthRate(),
+ serverDescriptor.getBandwidthBurst()),
+ serverDescriptor.getBandwidthObserved());
+ countedServerDescriptors++;
+ }
+ }
+ long endedMillis = System.currentTimeMillis();
+ System.out.println("Ending measureAverageAdvertisedBandwidth");
+ System.out.printf("Total time: %d millis%n",
+ endedMillis - startedMillis);
+ System.out.printf("Processed server descriptors: %d%n",
+ countedServerDescriptors);
+ System.out.printf("Average advertised bandwidth: %d%n",
+ sumAdvertisedBandwidth / countedServerDescriptors);
+ System.out.printf("Time per server descriptor: %.6f millis%n",
+ ((double) (endedMillis - startedMillis))
+ / ((double) countedServerDescriptors));
+ }
+}
diff --git a/docs/_static/example/benchmark_server_descriptor_stem.py b/docs/_static/example/benchmark_server_descriptor_stem.py
new file mode 100644
index 0000000..c475652
--- /dev/null
+++ b/docs/_static/example/benchmark_server_descriptor_stem.py
@@ -0,0 +1,21 @@
+import time
+import stem.descriptor
+
+def measure_average_advertised_bandwidth(path):
+ start_time = time.time()
+ total_bw, count = 0, 0
+
+ for desc in stem.descriptor.parse_file(path):
+ total_bw += min(desc.average_bandwidth, desc.burst_bandwidth, desc.observed_bandwidth)
+ count += 1
+
+ runtime = time.time() - start_time
+ print("Finished measure_average_advertised_bandwidth('%s')" % path)
+ print(' Total time: %i seconds' % runtime)
+ print(' Processed server descriptors: %i' % count)
+ print(' Average advertised bandwidth: %i' % (total_bw / count))
+ print(' Time per server descriptor: %0.5f seconds' % (runtime / count))
+ print('')
+
+if __name__ == '__main__':
+ measure_average_advertised_bandwidth('server-descriptors-2015-11.tar')
diff --git a/docs/_static/example/benchmark_server_descriptor_zoossh.go b/docs/_static/example/benchmark_server_descriptor_zoossh.go
new file mode 100644
index 0000000..f72b3fb
--- /dev/null
+++ b/docs/_static/example/benchmark_server_descriptor_zoossh.go
@@ -0,0 +1,68 @@
+package main
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+ "time"
+
+ "git.torproject.org/user/phw/zoossh.git"
+)
+
+var processedDescs int64 = 0
+var totalBw uint64 = 0
+
+func Min(a uint64, b uint64, c uint64) uint64 {
+ min := a
+
+ if b < min {
+ min = b
+ }
+
+ if c < min {
+ min = c
+ }
+
+ return min
+}
+
+func ProcessDescriptors(path string, info os.FileInfo, err error) error {
+ if _, err := os.Stat(path); err != nil {
+ return err
+ }
+
+ if info.IsDir() {
+ return nil
+ }
+
+ consensus, err := zoossh.ParseDescriptorFile(path)
+ if err != nil {
+ return err
+ }
+
+ if (processedDescs % 100) == 0 {
+ fmt.Printf(".")
+ }
+
+ for _, getDesc := range consensus.RouterDescriptors {
+ desc := getDesc()
+ totalBw += Min(desc.BandwidthAvg, desc.BandwidthBurst, desc.BandwidthObs)
+ processedDescs++
+ }
+
+ return nil
+}
+
+func main() {
+ before = time.Now()
+ filepath.Walk("server-descriptors-2015-11", ProcessDescriptors)
+ fmt.Println()
+ after = time.Now()
+
+ duration = after.Sub(before)
+ fmt.Println("Total time for descriptors:", duration)
+ fmt.Printf("Time per descriptor: %dns\n",
+ duration.Nanoseconds()/processedDescs)
+ fmt.Printf("Processed %d descriptors.\n", processedDescs)
+ fmt.Printf("Average advertised bandwidth: %d\n", totalBw/uint64(processedDescs))
+}
diff --git a/docs/_static/example/benchmark_stem.py b/docs/_static/example/benchmark_stem.py
new file mode 100644
index 0000000..8b71d73
--- /dev/null
+++ b/docs/_static/example/benchmark_stem.py
@@ -0,0 +1,81 @@
+import time
+import stem.descriptor
+
+def measure_average_advertised_bandwidth(path):
+ start_time = time.time()
+ total_bw, count = 0, 0
+
+ for desc in stem.descriptor.parse_file(path):
+ total_bw += min(desc.average_bandwidth, desc.burst_bandwidth, desc.observed_bandwidth)
+ count += 1
+
+ runtime = time.time() - start_time
+ print("Finished measure_average_advertised_bandwidth('%s')" % path)
+ print(' Total time: %i seconds' % runtime)
+ print(' Processed server descriptors: %i' % count)
+ print(' Average advertised bandwidth: %i' % (total_bw / count))
+ print(' Time per server descriptor: %0.5f seconds' % (runtime / count))
+ print('')
+
+def measure_countries_v3_requests(path):
+ start_time = time.time()
+ countries, count = set(), 0
+
+ for desc in stem.descriptor.parse_file(path):
+ if desc.dir_v3_responses:
+ countries.update(desc.dir_v3_responses.keys())
+
+ count += 1
+
+ runtime = time.time() - start_time
+ print("Finished measure_countries_v3_requests('%s')" % path)
+ print(' Total time: %i seconds' % runtime)
+ print(' Processed extrainfo descriptors: %i' % count)
+ print(' Number of countries: %i' % len(countries))
+ print(' Time per extrainfo descriptor: %0.5f seconds' % (runtime / count))
+ print('')
+
+def measure_average_relays_exit(path):
+ start_time = time.time()
+ total_relays, exits, consensuses = 0, 0, 0
+
+ for consensus in stem.descriptor.parse_file(path, document_handler = stem.descriptor.DocumentHandler.DOCUMENT):
+ for desc in consensus.routers.values():
+ if 'Exit' in desc.flags:
+ exits += 1
+
+ total_relays += 1
+
+ consensuses += 1
+
+ runtime = time.time() - start_time
+ print("Finished measure_average_relays_exit('%s')" % path)
+ print(' Total time: %i seconds' % runtime)
+ print(' Processed %i consensuses with %i router status entries' % (consensuses, total_relays))
+ print(' Total exits: %i (%0.2f%%)' % (exits, float(exits) / total_relays))
+ print(' Time per consensus: %0.5f seconds' % (runtime / consensuses))
+ print('')
+
+def measure_fraction_relays_exit_80_microdescriptors(path):
+ start_time = time.time()
+ exits, count = 0, 0
+
+ for desc in stem.descriptor.parse_file(path):
+ if desc.exit_policy.can_exit_to(port = 80):
+ exits += 1
+
+ count += 1
+
+ runtime = time.time() - start_time
+ print("Finished measure_fraction_relays_exit_80_microdescriptors('%s')" % path)
+ print(' Total time: %i seconds' % runtime)
+ print(' Processed microdescriptors: %i' % count)
+ print(' Total exits to port 80: %i (%0.2f%%)' % (exits, float(exits) / count))
+ print(' Time per microdescriptor: %0.5f seconds' % (runtime / count))
+ print('')
+
+measure_average_advertised_bandwidth('/home/atagar/Desktop/server-descriptors-2015-11.tar')
+measure_countries_v3_requests('/home/atagar/Desktop/extra-infos-2015-11.tar')
+measure_average_relays_exit('/home/atagar/Desktop/consensuses-2015-11.tar')
+measure_fraction_relays_exit_80_microdescriptors('/home/atagar/Desktop/microdescs-2015-11.tar')
+
diff --git a/docs/_static/example/benchmark_zoossh.go b/docs/_static/example/benchmark_zoossh.go
new file mode 100644
index 0000000..7cfc04f
--- /dev/null
+++ b/docs/_static/example/benchmark_zoossh.go
@@ -0,0 +1,120 @@
+package main
+
+import (
+ "fmt"
+ "log"
+ "os"
+ "path/filepath"
+ "time"
+
+ "git.torproject.org/user/phw/zoossh.git"
+)
+
+var processedCons int64 = 0
+var processedDescs int64 = 0
+var totalExits int64 = 0
+var totalRelays int64 = 0
+var totalBw uint64 = 0
+
+func Min(a uint64, b uint64, c uint64) uint64 {
+
+ min := a
+
+ if b < min {
+ min = b
+ }
+
+ if c < min {
+ min = c
+ }
+
+ return min
+}
+
+func ProcessDescriptors(path string, info os.FileInfo, err error) error {
+
+ if _, err := os.Stat(path); err != nil {
+ return err
+ }
+
+ if info.IsDir() {
+ return nil
+ }
+
+ consensus, err := zoossh.ParseDescriptorFile(path)
+ if err != nil {
+ return err
+ }
+
+ if (processedDescs % 100) == 0 {
+ fmt.Printf(".")
+ }
+
+ for _, getDesc := range consensus.RouterDescriptors {
+ desc := getDesc()
+ totalBw += Min(desc.BandwidthAvg, desc.BandwidthBurst, desc.BandwidthObs)
+ processedDescs++
+ }
+
+ return nil
+}
+
+func ProcessConsensus(path string, info os.FileInfo, err error) error {
+
+ if _, err := os.Stat(path); err != nil {
+ return err
+ }
+
+ if info.IsDir() {
+ return nil
+ }
+
+ consensus, err := zoossh.ParseConsensusFile(path)
+ if err != nil {
+ return err
+ }
+ fmt.Printf(".")
+
+ for _, getStatus := range consensus.RouterStatuses {
+ status := getStatus()
+ totalRelays++
+ if status.Flags.Exit == true {
+ totalExits++
+ }
+ }
+ processedCons++
+
+ return nil
+}
+
+func main() {
+
+ if len(os.Args) != 3 {
+ log.Fatalf("Usage: %s CONSENSUS_ARCHIVE DESCRIPTOR_ARCHIVE", os.Args[0])
+ }
+
+ before := time.Now()
+ filepath.Walk(os.Args[1], ProcessConsensus)
+ fmt.Println()
+ after := time.Now()
+
+ duration := after.Sub(before)
+ fmt.Println("Total time for consensuses:", duration)
+ fmt.Printf("Time per consensus: %dms\n",
+ duration.Nanoseconds()/processedCons/int64(1000000))
+ fmt.Printf("Processed %d consensuses with %d router status entries.\n",
+ processedCons, totalRelays)
+ fmt.Printf("Total exits: %d\n", totalExits)
+
+ before = time.Now()
+ filepath.Walk(os.Args[2], ProcessDescriptors)
+ fmt.Println()
+ after = time.Now()
+
+ duration = after.Sub(before)
+ fmt.Println("Total time for descriptors:", duration)
+ fmt.Printf("Time per descriptor: %dns\n",
+ duration.Nanoseconds()/processedDescs)
+ fmt.Printf("Processed %d descriptors.\n", processedDescs)
+ fmt.Printf("Average advertised bandwidth: %d\n", totalBw/uint64(processedDescs))
+}
diff --git a/docs/tutorials/mirror_mirror_on_the_wall.rst b/docs/tutorials/mirror_mirror_on_the_wall.rst
index ee524e4..656d228 100644
--- a/docs/tutorials/mirror_mirror_on_the_wall.rst
+++ b/docs/tutorials/mirror_mirror_on_the_wall.rst
@@ -263,31 +263,77 @@ Each library has its own capabilities...
.. role:: red
.. role:: green
-=========================== ================= =============== ==============
-Capability Stem Metrics-lib Zoossh
-=========================== ================= =============== ==============
-Language :green:`Python` :green:`Java` :green:`Go`
-Checks signatures :green:`Mostly` :red:`No` :red:`No`
-Create new descriptors :red:`No` :red:`No` :red:`No`
-Lazy parsing :green:`Yes` :red:`No` :green:`Yes`
-Type detection by @type :green:`Yes` :green:`Yes` :green:`Yes`
-Type detection by filename :green:`Yes` :red:`No` :red:`No`
-Packages :green:`Several` :red:`None` :red:`None`
+=========================== ===================== =================== ==============
+Capability Stem Metrics-lib Zoossh
+=========================== ===================== =================== ==============
+Language :green:`Python` :green:`Java` :green:`Go`
+Checks signatures :green:`Mostly` :red:`No` :red:`No`
+Create new descriptors :red:`No` :red:`No` :red:`No`
+Lazy parsing :green:`Yes` :red:`No` :green:`Yes`
+Type detection by @type :green:`Yes` :green:`Yes` :green:`Yes`
+Type detection by filename :green:`Yes` :red:`No` :red:`No`
+Packages :green:`Several` :red:`None` :red:`None`
**Can Read/Download From**
-Files :green:`Yes` :green:`Yes` :green:`Yes`
-Tarballs :green:`Yes` :green:`Yes` :red:`No`
-Tor Process :green:`Yes` :red:`No` :red:`No`
-Directory Authorities :green:`Yes` :green:`Yes` :red:`No`
-CollecTor :red:`No` :green:`Yes` :red:`No`
+Files :green:`Yes` :green:`Yes` :green:`Yes`
+Tarballs :green:`Yes` :green:`Yes` :red:`No`
+Tor Process :green:`Yes` :red:`No` :red:`No`
+Directory Authorities :green:`Yes` :green:`Yes` :red:`No`
+CollecTor :red:`No` :green:`Yes` :red:`No`
**Supported Types**
-Server Descriptors :green:`Yes` :green:`Yes` :green:`Partly`
-Extrainfo Descriptors :green:`Yes` :green:`Yes` :red:`No`
-Microdescriptors :green:`Yes` :green:`Yes` :red:`No`
-Consensus :green:`Yes` :green:`Yes` :green:`Partly`
-Bridge Descriptors :green:`Yes` :green:`Yes` :red:`No`
-Hidden Service Descriptors :green:`Yes` :red:`No` :red:`No`
-Bridge Pool Assignments :red:`No` :green:`Yes` :red:`No`
-Torperf :red:`No` :green:`Yes` :red:`No`
-Tordnsel :green:`Yes` :green:`Yes` :red:`No`
-=========================== ================= =============== ==============
+Server Descriptors :green:`Yes` :green:`Yes` :green:`Partly`
+Extrainfo Descriptors :green:`Yes` :green:`Yes` :red:`No`
+Microdescriptors :green:`Yes` :green:`Yes` :red:`No`
+Consensus :green:`Yes` :green:`Yes` :green:`Partly`
+Bridge Descriptors :green:`Yes` :green:`Yes` :red:`No`
+Hidden Service Descriptors :green:`Yes` :red:`No` :red:`No`
+Bridge Pool Assignments :red:`No` :green:`Yes` :red:`No`
+Torperf :red:`No` :green:`Yes` :red:`No`
+Tordnsel :green:`Yes` :green:`Yes` :red:`No`
+**Benchmarks**
+Server Descriptors :green:`0.63 ms` :green:`0.29 ms` :green:`0.46 ms`
+Extrainfo Descriptors :green:`0.42 ms` :green:`0.22 ms` :red:`unsupported`
+Microdescriptors :green:`0.34 ms` :green:`0.07 ms` :red:`unsupported`
+Consensus :green:`876.09 ms` :green:`246.71 ms` :green:`83.00 ms`
+Benchmarked With Commit :green:`c01a9cd` :green:`8767f3e` :green:`2380e55`
+Language Interpreter :green:`Python 3.5.1` :green:`Java 1.7.0` :green:`Go 1.5.2`
+=========================== ===================== =================== ==============
+
+Few things to note about these benchmarks...
+
+* **Zoossh is the fastest.** Its benchmarks were at a disadvantage due to not
+ reading from tarballs.
+
+* Your Python version makes a very large difference for Stem. For instance,
+ with Python 2.7 reading a consensus takes **1,393.10 ms** (almost twice as
+ long).
+
+* Metrics-lib and Stem can both read from compressed tarballs at a small
+ performance cost. For instance, Metrics-lib can read an `lzma compressed
+ <../faq.html#how-do-i-read-tar-xz-descriptor-archives>`_ consensus in
+ **255.76 ms** and Stem can do it in **913.12 ms**.
+
+So what does code with each of these look like?
+
+Stem Example
+------------
+
+* `Benchmark Script <../.../../_static/example/benchmark_stem.py>`_
+
+.. literalinclude:: /_static/example/benchmark_server_descriptor_stem.py
+ :language: python
+
+Metrics-lib Example
+-------------------
+
+* `Benchmark Script <../.../../_static/example/benchmark_metrics_lib.java>`_
+
+.. literalinclude:: /_static/example/benchmark_server_descriptor_metrics_lib.java
+ :language: java
+
+Zoossh Example
+--------------
+
+* `Benchmark Script <../.../../_static/example/benchmark_zoossh.go>`_
+.. literalinclude:: /_static/example/benchmark_server_descriptor_zoossh.go
+ :language: go
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits