Skip to content

Instantly share code, notes, and snippets.

@aliostad
Last active August 29, 2015 14:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aliostad/737d682f646e4425d4ba to your computer and use it in GitHub Desktop.
Save aliostad/737d682f646e4425d4ba to your computer and use it in GitHub Desktop.
Tool for benchmarking reads against Azure Table Storage
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<appSettings>
<add key="copy" value="false"/>
<add key="save" value="false"/>
</appSettings>
</configuration>
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Table;
namespace GetAllEntitiesByPK
{
class Program
{
static void Main(string[] args)
{
if (args.Length > 4 || args.Length < 3)
{
ConsoleWriteLine(ConsoleColor.White,
"GetAllEntitiesByPK.exe <connection string> <table name> <pk or pk file> [count]");
return;
}
string cn = args[0];
var tableName = args[1];
var pk = args[2];
var count = args.Length == 4
? Convert.ToInt32(args[3])
: 0;
Func<CloudTable> getTable = () =>
{
var account = CloudStorageAccount.Parse(cn);
var client = account.CreateCloudTableClient();
var table = client.GetTableReference(tableName);
return table;
};
var writer = new StreamWriter("results_" + Environment.TickCount)
{
AutoFlush = true
};
var times = new List<long>();
var stopwatch = new Stopwatch();
var tb = getTable();
int n = 0;
if (count == 0)
{
int k = 0;
foreach (var pkitem in File.ReadAllLines(pk))
{
stopwatch.Restart();
n = GetEntityByPK(tb, pkitem);
stopwatch.Stop();
times.Add(stopwatch.ElapsedMilliseconds);
writer.WriteLine(string.Format("{0}\t{1}\t{2}", pkitem, n, stopwatch.ElapsedMilliseconds));
ConsoleWrite(ConsoleColor.DarkYellow, "{0}\r", ++k);
}
}
else
{
for (int i = 0; i < count; i++)
{
stopwatch.Restart();
n = GetEntityByPK(tb, pk);
stopwatch.Stop();
times.Add(stopwatch.ElapsedMilliseconds);
writer.WriteLine(string.Format("{0}\t{1}\t{2}", pk, n, stopwatch.ElapsedMilliseconds));
ConsoleWrite(ConsoleColor.DarkYellow, "{0}\r", i);
}
}
Console.WriteLine();
Console.WriteLine();
times.Sort();
ConsoleWrite(ConsoleColor.Green, "Average: ");
ConsoleWriteLine(ConsoleColor.Magenta, times.Average(x => x).ToString());
ConsoleWrite(ConsoleColor.Green, "Min: ");
ConsoleWriteLine(ConsoleColor.Magenta, times.Min(x => x).ToString());
ConsoleWrite(ConsoleColor.Green, "Max: ");
ConsoleWriteLine(ConsoleColor.Magenta, times.Max(x => x).ToString());
ConsoleWrite(ConsoleColor.Green, "90th percentile: ");
ConsoleWriteLine(ConsoleColor.White, times[ 9 * times.Count / 10].ToString());
writer.Close();
}
private static int GetEntityByPK(CloudTable table, string pk)
{
int count = 0;
var entities = table.ExecuteQuery(new TableQuery().Where(TableQuery.GenerateFilterCondition("PartitionKey", "eq",
pk)));
if (Convert.ToBoolean(ConfigurationManager.AppSettings["save"]))
File.Delete(pk + ".entity");
foreach (var entity in entities)
{
Trace.WriteLine(entity);
if (Convert.ToBoolean(ConfigurationManager.AppSettings["copy"]))
InsertToCopyTable(entity);
if (Convert.ToBoolean(ConfigurationManager.AppSettings["save"]))
Save(entity);
count++;
}
return count;
}
private static CloudTable _copyTable;
private static void Save(DynamicTableEntity entity)
{
var sb = new StringBuilder();
sb.AppendFormat("{0}\t", entity.PartitionKey);
sb.AppendFormat("{0}\t", entity.RowKey);
sb.AppendFormat("{0}\t", entity.Timestamp);
sb.AppendFormat("{0}\t", entity.ETag);
foreach (var property in entity.Properties)
{
sb.AppendFormat("{0}\t", property.Value.PropertyAsObject);
}
File.AppendAllText(entity.PartitionKey + ".entity", sb.ToString());
}
private static void InsertToCopyTable(DynamicTableEntity entity)
{
if (_copyTable == null)
{
var account = CloudStorageAccount.Parse("DefaultEndpointsProtocol=http;AccountName=asos82perfbenchmarks;AccountKey=3GS5JqyKiHt+4eXz4C1tnTkkO/9x8Wsux/OvqFs8TZbJxwbLnDDWqZbMU7/FnGk5qDESxmdBzCBCfGW1zYrolg==");
var client = account.CreateCloudTableClient();
_copyTable = client.GetTableReference("Seeds");
_copyTable.CreateIfNotExists();
}
_copyTable.Execute(TableOperation.InsertOrReplace(entity));
}
private static void ConsoleWrite(ConsoleColor color, string value, params object[] args)
{
var foregroundColor = Console.ForegroundColor;
Console.ForegroundColor = color;
Console.Write(value, args);
Console.ForegroundColor = foregroundColor;
}
private static void ConsoleWriteLine(ConsoleColor color, string value, params object[] args)
{
var foregroundColor = Console.ForegroundColor;
Console.ForegroundColor = color;
Console.WriteLine(value, args);
Console.ForegroundColor = foregroundColor;
}
}
}
@aliostad
Copy link
Author

Tool to benchmark Azure Table Storage:

Usage:

GetAllEntitiesByPK.exe <storage connection string> <table name> <file where each line contains a PartitionKey>

Or

GetAllEntitiesByPK.exe <storage connection string> <table name> <Partition Key> <count>

It will display Min, Max, Avg and 90th percentile.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment