[tor-commits] [metrics-lib/master] Add benchmark code.

karsten at torproject.org karsten at torproject.org
Tue May 31 18:49:22 UTC 2016


commit 58fe9880434dc73c74779236ef1f3fcddeec933f
Author: Karsten Loesing <karsten.loesing at gmx.net>
Date:   Wed May 18 09:49:50 2016 +0200

    Add benchmark code.
    
    Implements #19051.
---
 CHANGELOG.md                                       |   1 +
 build.xml                                          |  13 +-
 .../descriptor/benchmark/MeasurePerformance.java   | 278 +++++++++++++++++++++
 3 files changed, 291 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index bfd4755..f694f84 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -22,6 +22,7 @@
      which would mean that only method 1 is supported.
    - Stop reporting "-----END .*-----" lines in directory key
      certificates as unrecognized.
+   - Add code used for benchmarking.
 
 
 # Changes in version 1.1.0 - 2015-12-28
diff --git a/build.xml b/build.xml
index 129c4ed..f77f83b 100644
--- a/build.xml
+++ b/build.xml
@@ -68,7 +68,7 @@
     </javadoc>
   </target>
 
-  <target name="test" depends="compile">
+  <target name="testcompile" depends="init">
     <javac destdir="${classes}"
            srcdir="${tests}"
            source="${source-and-target-java-version}"
@@ -80,6 +80,9 @@
            includeantruntime="false">
       <classpath refid="classpath"/>
     </javac>
+  </target>
+
+  <target name="test" depends="compile,testcompile">
     <junit fork="true" haltonfailure="true" printsummary="off">
       <classpath refid="classpath"/>
       <formatter type="plain" usefile="false"/>
@@ -90,6 +93,14 @@
     </junit>
   </target>
 
+  <target name="benchmark" depends="compile,testcompile">
+    <java fork="true"
+          maxmemory="2048m"
+          classname="org.torproject.descriptor.benchmark.MeasurePerformance">
+      <classpath refid="classpath"/>
+    </java>
+  </target>
+
   <target name="jar" depends="compile">
     <exec executable="git" outputproperty="git.revision">
       <arg value="rev-parse" />
diff --git a/test/org/torproject/descriptor/benchmark/MeasurePerformance.java b/test/org/torproject/descriptor/benchmark/MeasurePerformance.java
new file mode 100644
index 0000000..a52020a
--- /dev/null
+++ b/test/org/torproject/descriptor/benchmark/MeasurePerformance.java
@@ -0,0 +1,278 @@
+/* Copyright 2016 The Tor Project
+ * See LICENSE for licensing information */
+package org.torproject.descriptor.benchmark;
+
+import org.torproject.descriptor.Descriptor;
+import org.torproject.descriptor.DescriptorFile;
+import org.torproject.descriptor.DescriptorReader;
+import org.torproject.descriptor.DescriptorSourceFactory;
+import org.torproject.descriptor.ExtraInfoDescriptor;
+import org.torproject.descriptor.Microdescriptor;
+import org.torproject.descriptor.NetworkStatusEntry;
+import org.torproject.descriptor.RelayNetworkStatusConsensus;
+import org.torproject.descriptor.ServerDescriptor;
+
+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;
+    }
+    measureAverageAdvertisedBandwidth(new File(resDir, resPaths[0]));
+    pause();
+    measureAverageAdvertisedBandwidth(new File(resDir, resPaths[1]));
+    pause();
+    measureAverageAdvertisedBandwidth(new File(resDir, resPaths[2]));
+    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]));
+    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.tar.xz",
+    "archive/relay-descriptors/microdescs/microdescs-2015-11.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("Missing resource: " + resDir + "/" + resPath);
+        return false;
+      }
+    }
+    return true;
+  }
+
+  private static void pause() {
+    try {
+      Thread.sleep(15L * 1000L);
+    } catch (InterruptedException e) {
+      e.printStackTrace();
+    }
+  }
+
+  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 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 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));
+  }
+}
+





More information about the tor-commits mailing list