Remove obsolete perf analyses

This commit is contained in:
Ilya Ig. Petrov 2017-08-26 20:49:39 +05:00
parent d5aa1bab71
commit f74397b75d
15 changed files with 0 additions and 30050 deletions

View File

@ -1,26 +0,0 @@
## PAC-Script Performance Analysis
Somewhere in PAC-script you may want:
```javascript
if (Is_subdomain_of( host, blocked_hosts ))
return 'use proxy';
```
You have to make `Is_subdomain_of` very fast.
This check is executed on each request. You should watch memeory consumption too.
The naive solution is to keep array of blocked ips and check if the host resolves to one of the ips.
You may do it with `indexOf`, binary search, etc.
The shortcoming of every ip solution is that __some providers resolve blocked hosts to wrong ips__, so we eventually need list of hosts.
I have tested different [solutions](https://github.com/ilyaigpetrov/anti-censorship-russia/tree/master/pac-generator/src), and depicted [results](./benchmark/Output.txt) in the following chart:
![Host Lookup Chart: Time-Memory, Hits-Misses](./chart/host-lookup-chart.png)
* __IPs indexOf__ Blocked IP is searched by `indexOf`
* __IPs binary__ Blocked IP is searched by binary search. For some reason hit time is slightly increased.
* __IPs switch__ Simply `switch(Blocked_IP) { case1: ... caseN: return true }`. Works even better than binary search. Magic.
* __Hosts switch__ Radix trie built on `switch`. Comparable to __IPs switch__.
* __Hosts reversed binary__ binary search on hosts, but hosts are kept in reversed form: _"gro.evichra"_ instead of _"archive.org"_. It shouldn't really affect anything, but it does, maybe because I also use `dnsDomainIs` instead of `===`.

View File

@ -1 +0,0 @@
bin

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,89 +0,0 @@
blocked-hosts-reversed-binary.js: 371 bytes, 3633268 ns, Missed: 331 bytes, 959025 ns
blocked-hosts-switch.js: 35 bytes, 861416 ns, Missed: 54 bytes, 1009980 ns
blocked-hosts-binary.js: 355 bytes, 3741660 ns, Missed: 315 bytes, 1101475 ns
blocked-hosts-plain-switch.js: 368 bytes, 4595046 ns, Missed: 327 bytes, 1181185 ns
blocked-ips-indexOf.js: 30 bytes, 4744851 ns, Missed: 50 bytes, 949647 ns
blocked-ips-switch.js: 30 bytes, 1324520 ns, Missed: 50 bytes, 954300 ns
blocked-ips-binary.js: 30 bytes, 3528872 ns, Missed: 50 bytes, 955016 ns
======================
blocked-hosts-reversed-binary.js: 60 bytes, 3810837 ns, Missed: 71 bytes, 971006 ns
blocked-hosts-switch.js: 90 bytes, 881944 ns, Missed: 54 bytes, 987749 ns
blocked-hosts-binary.js: 352 bytes, 3715816 ns, Missed: 311 bytes, 1015559 ns
blocked-hosts-plain-switch.js: 367 bytes, 5108743 ns, Missed: 322 bytes, 1057506 ns
blocked-ips-switch.js: 32 bytes, 1331517 ns, Missed: 48 bytes, 952596 ns
blocked-ips-indexOf.js: 36 bytes, 4863773 ns, Missed: 50 bytes, 956231 ns
blocked-ips-binary.js: 33 bytes, 3724425 ns, Missed: 52 bytes, 958463 ns
======================
blocked-hosts-plain-switch.js: 367 bytes, 3895654 ns, Missed: 218 bytes, 590817 ns
blocked-hosts-binary.js: 351 bytes, 4559283 ns, Missed: 207 bytes, 595531 ns
blocked-hosts-reversed-binary.js: 367 bytes, 3757800 ns, Missed: 96 bytes, 607930 ns
blocked-hosts-switch.js: 85 bytes, 909670 ns, Missed: 82 bytes, 665152 ns
blocked-ips-switch.js: 34 bytes, 1326365 ns, Missed: 72 bytes, 583463 ns
blocked-ips-binary.js: 36 bytes, 3567749 ns, Missed: 77 bytes, 583504 ns
blocked-ips-indexOf.js: 37 bytes, 4794414 ns, Missed: 77 bytes, 584845 ns
======================
blocked-hosts-binary.js: 355 bytes, 3669894 ns, Missed: 207 bytes, 593995 ns
blocked-hosts-plain-switch.js: 363 bytes, 3977687 ns, Missed: 223 bytes, 594579 ns
blocked-hosts-switch.js: 89 bytes, 874404 ns, Missed: 81 bytes, 608442 ns
blocked-hosts-reversed-binary.js: 54 bytes, 3706841 ns, Missed: 96 bytes, 622309 ns
blocked-ips-indexOf.js: 35 bytes, 4839284 ns, Missed: 78 bytes, 587725 ns
blocked-ips-switch.js: 43 bytes, 1346437 ns, Missed: 77 bytes, 599972 ns
blocked-ips-binary.js: 33 bytes, 3651593 ns, Missed: 80 bytes, 621814 ns
======================
blocked-hosts-binary.js: 352 bytes, 3711255 ns, Missed: 207 bytes, 590903 ns
blocked-hosts-switch.js: 91 bytes, 863216 ns, Missed: 77 bytes, 592086 ns
blocked-hosts-reversed-binary.js: 371 bytes, 3690426 ns, Missed: 99 bytes, 595659 ns
blocked-hosts-plain-switch.js: 367 bytes, 3933146 ns, Missed: 218 bytes, 618715 ns
blocked-ips-indexOf.js: 34 bytes, 4861233 ns, Missed: 77 bytes, 592716 ns
blocked-ips-switch.js: 30 bytes, 1339607 ns, Missed: 84 bytes, 595159 ns
blocked-ips-binary.js: 31 bytes, 3552007 ns, Missed: 76 bytes, 603872 ns
======================
blocked-hosts-binary-trie.js: 364 bytes, 27134555ns, Missed: 218 bytes, 725467 ns
blocked-hosts-simple-trie.js: 364 bytes, 4085395 ns, Missed: 219 bytes, 649011 ns
======================
blocked-hosts-plain-switch.js: 69 bytes, 2850095 ns, Missed: 96 bytes, 590933 ns
blocked-hosts-switch.js: 93 bytes, 854636 ns, Missed: 77 bytes, 597410 ns
blocked-hosts-reversed-binary.js: 109 bytes, 3710108 ns, Missed: 96 bytes, 604745 ns
blocked-hosts-hash.js: 351 bytes, 5112411 ns, Missed: 203 bytes, 605303 ns
blocked-hosts-binary.js: 355 bytes, 3691874 ns, Missed: 207 bytes, 615506 ns
blocked-ips-binary.js: 33 bytes, 3558958 ns, Missed: 81 bytes, 607783 ns
blocked-ips-indexOf.js: 35 bytes, 4832252 ns, Missed: 77 bytes, 593958 ns
blocked-ips-switch.js: 36 bytes, 1341637 ns, Missed: 76 bytes, 613332 ns
======================
blocked-hosts-binary.js: 356 bytes, 3763269 ns, Missed: 211 bytes, 595469 ns
blocked-hosts-plain-switch.js: 364 bytes, 2865722 ns, Missed: 223 bytes, 597233 ns
blocked-hosts-reversed-binary.js: 106 bytes, 3680757 ns, Missed: 96 bytes, 604607 ns
blocked-hosts-switch.js: 93 bytes, 865423 ns, Missed: 81 bytes, 606328 ns
blocked-hosts-hash.js: 347 bytes, 5163575 ns, Missed: 207 bytes, 607421 ns
blocked-ips-indexOf.js: 33 bytes, 4845498 ns, Missed: 77 bytes, 594833 ns
blocked-ips-switch.js: 35 bytes, 1345531 ns, Missed: 77 bytes, 601800 ns
blocked-ips-binary.js: 38 bytes, 3575806 ns, Missed: 80 bytes, 608611 ns
======================
blocked-hosts-reversed-binary.js: 109 bytes, 3704594 ns, Missed: 96 bytes, 602820 ns
blocked-hosts-binary.js: 351 bytes, 3718253 ns, Missed: 210 bytes, 605188 ns
blocked-hosts-plain-switch.js: 367 bytes, 2874843 ns, Missed: 88 bytes, 607200 ns
blocked-hosts-hash.js: 347 bytes, 5062512 ns, Missed: 207 bytes, 609278 ns
blocked-hosts-switch.js: 88 bytes, 894410 ns, Missed: 77 bytes, 614169 ns
blocked-ips-switch.js: 37 bytes, 1348111 ns, Missed: 72 bytes, 597439 ns
blocked-ips-indexOf.js: 35 bytes, 4853437 ns, Missed: 72 bytes, 599850 ns
blocked-ips-binary.js: 31 bytes, 3542401 ns, Missed: 77 bytes, 602958 ns
======================
blocked-hosts-binary.js: 351 bytes, 3729603 ns, Missed: 211 bytes, 608708 ns
blocked-hosts-hash.js: 347 bytes, 5009832 ns, Missed: 207 bytes, 610767 ns
blocked-hosts-plain-switch.js: 33 bytes, 2979803 ns, Missed: 94 bytes, 617564 ns
blocked-hosts-reversed-binary.js: 108 bytes, 3771339 ns, Missed: 96 bytes, 600923 ns
blocked-hosts-switch.js: 88 bytes, 886985 ns, Missed: 81 bytes, 611207 ns
blocked-ips-binary.js: 33 bytes, 3518561 ns, Missed: 77 bytes, 614293 ns
blocked-ips-indexOf.js: 36 bytes, 4876239 ns, Missed: 80 bytes, 608928 ns
blocked-ips-switch-trie-index.js: 55 bytes, 831119 ns, Missed: 97 bytes, 606306 ns
blocked-ips-switch-trie.js: 43 bytes, 836457 ns, Missed: 86 bytes, 641512 ns
blocked-ips-switch.js: 31 bytes, 1401377 ns, Missed: 72 bytes, 637717 ns

View File

@ -1,121 +0,0 @@
using System;
using System.IO;
using PacProxyUsage;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
public class Program
{
public static string RunTest(string hostsFile, string pacName, bool ifMissing = false) {
using(StreamReader hostsReader = new StreamReader(hostsFile))
{
string pacUri = "http://localhost:8080/"+pacName+"?"+new Random().Next();
Console.WriteLine(pacUri);
GC.Collect();
long memBefore = GC.GetTotalMemory(true);
var myTimer = new QueryPerfCounter();
myTimer.Start();
int iterations = 0;
string host;
while( (host = hostsReader.ReadLine()) != null )
{
string uri = Proxy.GetProxyForUrlUsingPac( "http://"+host, pacUri );
if (ifMissing && uri != null || !ifMissing && uri == null)
Console.WriteLine("DIRECT !" + host + "!");
//else Console.WriteLine("PROXY !" + uri + "!"); // For DEBUG.
++iterations;
}
myTimer.Stop();
// Calculate time per iteration in nanoseconds
double duration = myTimer.Duration(iterations);
long memAfter = GC.GetTotalMemory(false);
long memUsage = memAfter - memBefore;
double memPerAddr = memUsage / (double) iterations;
var resultNs = Convert.ToInt32(duration).ToString();
var resultBytes = Convert.ToInt32(memPerAddr).ToString();
return string.Format( "{0} bytes, {1} ns", resultBytes, resultNs );
}
}
public static void Main(string[] args)
{
if (args.Length != 1 || !Directory.Exists(args[0]))
{
Console.WriteLine("Arguments: PACs-dir.\nPac scripts must be served from the root of localhost:8080.");
return;
}
bool ifAppend = true;
using (StreamWriter resultsWriter = new StreamWriter("Output.txt", ifAppend))
{
resultsWriter.WriteLine("======================");
var pacsPath = args[0];
string [] pacs = Directory.GetFiles(pacsPath);
foreach(string pacPath in pacs)
{
string pacName = Path.GetFileName(pacPath);
Regex r = new Regex(@"^(\w+-\w+)", RegexOptions.IgnoreCase);
Match m = r.Match(pacName);
var prefix = m.Groups[1].ToString();
var hostsFile = "./Inputs/"+prefix + ".txt";
var missedFile = "./Inputs/missed.txt";
var results = pacName+": "+RunTest(hostsFile, pacName) + ", Missed: "+RunTest(missedFile, pacName, true);
Console.WriteLine(results);
resultsWriter.WriteLine(results);
}
}
}
}
public class QueryPerfCounter
{
[DllImport("KERNEL32")]
private static extern bool QueryPerformanceCounter(
out long lpPerformanceCount);
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceFrequency(out long lpFrequency);
private long start;
private long stop;
private long frequency;
Decimal multiplier = new Decimal(1.0e9);
public QueryPerfCounter()
{
if (QueryPerformanceFrequency(out frequency) == false)
{
// Frequency not supported
throw new Exception();
}
}
public void Start()
{
QueryPerformanceCounter(out start);
}
public void Stop()
{
QueryPerformanceCounter(out stop);
}
public double Duration(int iterations)
{
return ((((double)(stop - start)* (double) multiplier) / (double) frequency)/iterations);
}
}

View File

@ -1,46 +0,0 @@
using System;
namespace PacProxyUsage
{
/// <summary>
/// Summary description for Proxy.
/// </summary>
public class Proxy
{
public Proxy()
{
}
/// <summary>
/// Return proxy for requested Url
/// </summary>
/// <param name="sUrl">url</param>
/// <param name="sPacUri">Uri to PAC file</param>
/// <returns>proxy info</returns>
public static string GetProxyForUrlUsingPac ( string DestinationUrl, string PacUri ){
IntPtr WinHttpSession = Win32Api.WinHttpOpen("User", Win32Api.WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, IntPtr.Zero, IntPtr.Zero, 0);
Win32Api.WINHTTP_AUTOPROXY_OPTIONS ProxyOptions = new Win32Api.WINHTTP_AUTOPROXY_OPTIONS();
Win32Api.WINHTTP_PROXY_INFO ProxyInfo = new Win32Api.WINHTTP_PROXY_INFO();
ProxyOptions.fAutoLoginIfChallenged = true;
ProxyOptions.dwFlags = Win32Api.WINHTTP_AUTOPROXY_CONFIG_URL;
ProxyOptions.dwAutoDetectFlags = (Win32Api.WINHTTP_AUTO_DETECT_TYPE_DHCP | Win32Api.WINHTTP_AUTO_DETECT_TYPE_DNS_A);
ProxyOptions.lpszAutoConfigUrl = PacUri;
// Get Proxy
bool IsSuccess = Win32Api.WinHttpGetProxyForUrl( WinHttpSession, DestinationUrl, ref ProxyOptions, ref ProxyInfo );
Win32Api.WinHttpCloseHandle(WinHttpSession);
if ( IsSuccess ){
return ProxyInfo.lpszProxy;
}else {
Console.WriteLine("Error: {0}", Win32Api.GetLastError() );
return null;
}
}
}
}

View File

@ -1,204 +0,0 @@
using System;
using System.Runtime.InteropServices;
namespace PacProxyUsage
{
/// <summary>
/// Summary description for Win32Api.
/// </summary>
public class Win32Api
{
#region AutoProxy Constants
/// <summary>
/// Applies only when setting proxy information
/// </summary>
public const int WINHTTP_ACCESS_TYPE_DEFAULT_PROXY = 0;
/// <summary>
/// Internet accessed through a direct connection
/// </summary>
public const int WINHTTP_ACCESS_TYPE_NO_PROXY = 1;
/// <summary>
/// Internet accessed using a proxy
/// </summary>
public const int WINHTTP_ACCESS_TYPE_NAMED_PROXY = 3;
/// <summary>
/// Attempt to automatically discover the URL of the
/// PAC file using both DHCP and DNS queries to the local network.
/// </summary>
public const int WINHTTP_AUTOPROXY_AUTO_DETECT = 0x00000001;
/// <summary>
/// Download the PAC file from the URL in the WINHTTP_AUTOPROXY_OPTIONS structure.
/// </summary>
public const int WINHTTP_AUTOPROXY_CONFIG_URL = 0x00000002;
/// <summary>
/// Executes the Web Proxy Auto-Discovery (WPAD) protocol in-process instead of
/// delegating to an out-of-process WinHTTP AutoProxy Service, if available.
/// This flag must be combined with one of the other flags
/// </summary>
public const int WINHTTP_AUTOPROXY_RUN_INPROCESS = 0x00010000;
/// <summary>
/// By default, WinHTTP is configured to fall back to auto-discover a proxy
/// in-process. If this fallback behavior is undesirable in the event that
/// an out-of-process discovery fails, it can be disabled using this flag.
/// </summary>
public const int WINHTTP_AUTOPROXY_RUN_OUTPROCESS_ONLY = 0x00020000;
/// <summary>
/// Use DHCP to locate the proxy auto-configuration file.
/// </summary>
public const int WINHTTP_AUTO_DETECT_TYPE_DHCP = 0x00000001;
/// <summary>
/// Use DNS to attempt to locate the proxy auto-configuration file at a
/// well-known location on the domain of the local computer
/// </summary>
public const int WINHTTP_AUTO_DETECT_TYPE_DNS_A = 0x00000002;
#endregion
#region Proxy Structures
/// <summary>
/// The structure is used to indicate to the WinHttpGetProxyForURL
/// function whether to specify the URL of the Proxy Auto-Configuration
/// (PAC) file or to automatically locate the URL with DHCP or DNS
/// queries to the network
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
public struct WINHTTP_AUTOPROXY_OPTIONS {
/// <summary>
/// Mechanisms should be used to obtain the PAC file
/// </summary>
[MarshalAs(UnmanagedType.U4)]
public int dwFlags;
/// <summary>
/// If dwflags includes the WINHTTP_AUTOPROXY_AUTO_DETECT flag,
/// then dwAutoDetectFlags specifies what protocols are to be
/// used to locate the PAC file. If both the DHCP and DNS auto
/// detect flags are specified, then DHCP is used first;
/// if no PAC URL is discovered using DHCP, then DNS is used.
/// If dwflags does not include the WINHTTP_AUTOPROXY_AUTO_DETECT
/// flag, then dwAutoDetectFlags must be zero.
/// </summary>
[MarshalAs(UnmanagedType.U4)]
public int dwAutoDetectFlags;
/// <summary>
/// If dwflags includes the WINHTTP_AUTOPROXY_CONFIG_URL flag, the
/// lpszAutoConfigUrl must point to a null-terminated Unicode string
/// that contains the URL of the proxy auto-configuration (PAC) file.
/// If dwflags does not include the WINHTTP_AUTOPROXY_CONFIG_URL flag,
/// then lpszAutoConfigUrl must be NULL.
/// </summary>
public string lpszAutoConfigUrl;
/// <summary>
/// Reserved for future use; must be NULL.
/// </summary>
public IntPtr lpvReserved;
/// <summary>
/// Reserved for future use; must be zero.
/// </summary>
[MarshalAs(UnmanagedType.U4)]
public int dwReserved;
/// <summary>
/// Specifies whether the client's domain credentials should be automatically
/// sent in response to an NTLM or Negotiate Authentication challenge when
/// WinHTTP requests the PAC file.
/// If this flag is TRUE, credentials should automatically be sent in response
/// to an authentication challenge. If this flag is FALSE and authentication
/// is required to download the PAC file, the WinHttpGetProxyForUrl fails.
/// </summary>
[MarshalAs(UnmanagedType.Bool)]
public bool fAutoLoginIfChallenged;
}
/// <summary>
/// The structure contains the session or default proxy configuration.
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
public struct WINHTTP_PROXY_INFO {
/// <summary>
/// Unsigned long integer value that contains the access type
/// </summary>
[MarshalAs(UnmanagedType.U4)]
public int dwAccessType;
/// <summary>
/// Pointer to a string value that contains the proxy server list
/// </summary>
public string lpszProxy;
/// <summary>
/// Pointer to a string value that contains the proxy bypass list
/// </summary>
public string lpszProxyBypass;
}
#endregion
#region WinHttp
/// <summary>
/// This function implements the Web Proxy Auto-Discovery (WPAD) protocol
/// for automatically configuring the proxy settings for an HTTP request.
/// The WPAD protocol downloads a Proxy Auto-Configuration (PAC) file,
/// which is a script that identifies the proxy server to use for a given
/// target URL. PAC files are typically deployed by the IT department within
/// a corporate network environment. The URL of the PAC file can either be
/// specified explicitly or WinHttpGetProxyForUrl can be instructed to
/// automatically discover the location of the PAC file on the local network.
/// </summary>
/// <param name="hSession">The WinHTTP session handle returned by the WinHttpOpen function</param>
/// <param name="lpcwszUrl">A pointer to a null-terminated Unicode string that contains the
/// URL of the HTTP request that the application is preparing to send.</param>
/// <param name="pAutoProxyOptions">A pointer to a WINHTTP_AUTOPROXY_OPTIONS structure that
/// specifies the auto-proxy options to use.</param>
/// <param name="pProxyInfo">A pointer to a WINHTTP_PROXY_INFO structure that receives the
/// proxy setting. This structure is then applied to the request handle using the
/// WINHTTP_OPTION_PROXY option.</param>
/// <returns></returns>
[DllImport("winhttp.dll", SetLastError=true, CharSet=CharSet.Unicode)]
public static extern bool WinHttpGetProxyForUrl(
IntPtr hSession,
string lpcwszUrl,
ref WINHTTP_AUTOPROXY_OPTIONS pAutoProxyOptions,
ref WINHTTP_PROXY_INFO pProxyInfo);
/// <summary>
/// The function initializes, for an application, the use of WinHTTP
/// functions and returns a WinHTTP-session handle
/// </summary>
/// <param name="pwszUserAgent">A pointer to a string variable that contains the name of the
/// application or entity calling the WinHTTP functions.</param>
/// <param name="dwAccessType">Type of access required. This can be one of the following values</param>
/// <param name="pwszProxyName"> A pointer to a string variable that contains the name of the
/// proxy server to use when proxy access is specified by setting dwAccessType to
/// WINHTTP_ACCESS_TYPE_NAMED_PROXY. The WinHTTP functions recognize only CERN type proxies for HTTP.
/// If dwAccessType is not set to WINHTTP_ACCESS_TYPE_NAMED_PROXY, this parameter must be set
/// to WINHTTP_NO_PROXY_NAME</param>
/// <param name="pwszProxyBypass">A pointer to a string variable that contains an optional list
/// of host names or IP addresses, or both, that should not be routed through the proxy when
/// dwAccessType is set to WINHTTP_ACCESS_TYPE_NAMED_PROXY. The list can contain wildcard characters.
/// Do not use an empty string, because the WinHttpOpen function uses it as the proxy bypass list.
/// If this parameter specifies the "&lt;local&gt;" macro as the only entry, this function bypasses
/// any host name that does not contain a period. If dwAccessType is not set to WINHTTP_ACCESS_TYPE_NAMED_PROXY,
/// this parameter must be set to WINHTTP_NO_PROXY_BYPASS.</param>
/// <param name="dwFlags">Unsigned long integer value that contains the flags that indicate various options
/// affecting the behavior of this function</param>
/// <returns>Returns a valid session handle if successful, or NULL otherwise</returns>
[DllImport("winhttp.dll", SetLastError=true, CharSet=CharSet.Unicode)]
public static extern IntPtr WinHttpOpen(
string pwszUserAgent,
int dwAccessType,
IntPtr pwszProxyName,
IntPtr pwszProxyBypass,
int dwFlags
);
/// <summary>
/// The function closes a single HINTERNET handle
/// </summary>
/// <param name="hInternet">Valid HINTERNET handle to be closed.</param>
/// <returns>Returns TRUE if the handle is successfully closed, or FALSE otherwise</returns>
[DllImport("winhttp.dll", SetLastError=true, CharSet=CharSet.Unicode)]
public static extern bool WinHttpCloseHandle(IntPtr hInternet);
#endregion
[DllImport("kernel32.dll")]
public static extern int GetLastError();
}
}

View File

@ -1,10 +0,0 @@
{
"version": "0.1-alpha",
"authors": ["ilyaigpetrov"],
"description": "A wonderful library that does nice stuff",
"code": ["**/*.cs"],
"frameworks": {
"dnx451": { }
}
}

View File

@ -1,14 +0,0 @@
{
"locked": false,
"version": 2,
"targets": {
"DNX,Version=v4.5.1": {},
"DNX,Version=v4.5.1/win7-x86": {},
"DNX,Version=v4.5.1/win7-x64": {}
},
"libraries": {},
"projectFileDependencyGroups": {
"": [],
"DNX,Version=v4.5.1": []
}
}

View File

@ -1,2 +0,0 @@
Dual-scale-D3-Bar-Chart
========================

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View File

@ -1,9 +0,0 @@
approach memHit timeHit memMiss timeMiss
Hosts reversed binary 109 3704594 96 602820
Hosts binary 351 3718253 210 605188
Hosts plain switch 367 2874843 88 607200
Hosts hash 347 5062512 207 609278
Hosts switch 88 894410 77 614169
IPs switch 37 1348111 72 597439
IPs indexOf 35 4853437 72 599850
IPs binary 31 3542401 77 602958
1 approach memHit timeHit memMiss timeMiss
2 Hosts reversed binary 109 3704594 96 602820
3 Hosts binary 351 3718253 210 605188
4 Hosts plain switch 367 2874843 88 607200
5 Hosts hash 347 5062512 207 609278
6 Hosts switch 88 894410 77 614169
7 IPs switch 37 1348111 72 597439
8 IPs indexOf 35 4853437 72 599850
9 IPs binary 31 3542401 77 602958

View File

@ -1,182 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 12px Tahoma;
}
.y.axisRight text {
fill: orange;
}
.y.axisLeft text {
fill: steelblue;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.timeMiss {
fill: red;
}
.memMiss {
fill: blue;
}
.timeHit {
fill: orange;
}
.memHit {
fill: steelblue;
}
.x.axis path {
display: none;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var margin = {top: 80, right: 80, bottom: 80, left: 80},
width = 1000 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var y0 = d3.scale.linear().domain([0, 400]).range([height, 0]);
var y1 = d3.scale.linear().domain([0, 6000000]).range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
// create left yAxis
var yAxisLeft = d3.svg.axis().scale(y0).ticks(4).orient("left");
// create right yAxis
var yAxisRight = d3.svg.axis().scale(y1).ticks(6).orient("right");
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("class", "graph")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
function type(d) {
d.memMiss = +d.memMiss;
return d;
}
d3.tsv("data.tsv", type, function(error, data) {
x.domain(data.map( d => d.approach ));
//y0.domain([0, d3.max(data, d => Math.max(d.memHit, d.memMiss) )]);
//y1.domain([0, d3.max(data, d => Math.max(d.timeHit, d.timeMiss) )]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis axisLeft")
.attr("transform", "translate(0,0)")
.call(yAxisLeft)
.append("text")
.attr("y", 6)
.attr("dy", "-2em")
.attr("dx", "-2em")
.style("text-anchor", "right")
.text("bytes per request");
svg.append("g")
.attr("class", "y axis axisRight")
.attr("transform", "translate(" + (width) + ",0)")
.call(yAxisRight)
.append("text")
.attr("y", 6)
.attr("dy", "-2em")
.attr("dx", "-1em")
.style("text-anchor", "start")
.text("ns per request");
bars = svg.selectAll(".bar").data(data).enter();
bars.append("rect")
.attr("class", "memHit")
.attr("width", x.rangeBand()*0.25*0.5 )
.attr("x", d => x(d.approach) + x.rangeBand()*0.25 )
.attr("y", d => y0(d.memHit) )
.attr("height", (d,i,j) => height - y0(d.memHit) );
bars.append("rect")
.attr("class", "timeHit")
.attr("x", d => x(d.approach) + x.rangeBand()*0.25*1.5 )
.attr("width", x.rangeBand()*0.25*0.5 )
.attr("y", d => y1(d.timeHit) )
.attr("height", (d,i,j) => height - y1(d.timeHit) );
bars.append("rect")
.attr("class", "memMiss")
.attr("x", d => x(d.approach) + x.rangeBand()*0.25*2 )
.attr("width", x.rangeBand()*0.25*0.5 )
.attr("y", d => y0(d.memMiss) )
.attr("height", (d,i,j) => height - y0(d.memMiss) );
bars.append("rect")
.attr("class", "timeMiss")
.attr("x", d => x(d.approach) + x.rangeBand()*0.25*2.5 )
.attr("width", x.rangeBand()*0.25*0.5 )
.attr("y", d => y1(d.timeMiss) )
.attr("height", (d,i,j) => height - y1(d.timeMiss) );
// add legend
var color_hash = {
0 : ["Time / Miss", "red"],
1 : ["Memory / Miss", "blue"],
2 : ["Time / Hit", "orange"],
3 : ["Memory / Hit", "steelblue"]
}
var legend = svg.append("g")
.attr("class", "legend")
.attr("x", width - 65)
.attr("y", 25)
.attr("height", 100)
.attr("width", 100);
legend.selectAll('g')
.data(data)
.enter()
.append('g')
.each(function(d, i) {
if(i > 3)
return; // Approach.
var g = d3.select(this);
g.append("rect")
.attr("x", width - x.rangeBand()*3.5 - 15)
.attr("y", i*25)
.attr("width", 10)
.attr("height", 10)
.style("fill", color_hash[i][1]);
g.append("text")
.attr("x", width - x.rangeBand()*3.5)
.attr("y", i * 25 + 8)
.attr("height",30)
.attr("width",100)
.style("fill", color_hash[i][1])
.text(color_hash[i][0]);
});
});
</script>