diff --git a/.gitmodules b/.gitmodules index 6fb530f..0f6d826 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "test/mvt-fixtures"] path = test/mvt-fixtures url = https://github.com/mapbox/mvt-fixtures.git +[submodule "bench/mvt-bench-fixtures"] + path = bench/mvt-bench-fixtures + url = https://github.com/mapbox/mvt-bench-fixtures.git diff --git a/VectorTileCs.sln b/VectorTileCs.sln index 50ab856..ad01399 100644 --- a/VectorTileCs.sln +++ b/VectorTileCs.sln @@ -15,6 +15,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Util", "src\Util\Util.cspro EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VectorTiles.Tests", "src\VectorTiles.Tests\VectorTiles.Tests.csproj", "{067456C0-086C-46A8-B37F-1405717B7BFC}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Bench", "src\Bench\Bench.csproj", "{5FA56C72-348A-4B52-980C-EA8287E66422}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -71,6 +73,14 @@ Global {067456C0-086C-46A8-B37F-1405717B7BFC}.Release|Any CPU.Build.0 = Release|Any CPU {067456C0-086C-46A8-B37F-1405717B7BFC}.Release|x64.ActiveCfg = Release|Any CPU {067456C0-086C-46A8-B37F-1405717B7BFC}.Release|x64.Build.0 = Release|Any CPU + {5FA56C72-348A-4B52-980C-EA8287E66422}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5FA56C72-348A-4B52-980C-EA8287E66422}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5FA56C72-348A-4B52-980C-EA8287E66422}.Debug|x64.ActiveCfg = Debug|Any CPU + {5FA56C72-348A-4B52-980C-EA8287E66422}.Debug|x64.Build.0 = Debug|Any CPU + {5FA56C72-348A-4B52-980C-EA8287E66422}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5FA56C72-348A-4B52-980C-EA8287E66422}.Release|Any CPU.Build.0 = Release|Any CPU + {5FA56C72-348A-4B52-980C-EA8287E66422}.Release|x64.ActiveCfg = Release|Any CPU + {5FA56C72-348A-4B52-980C-EA8287E66422}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/appveyor.yml b/appveyor.yml index 9d4a30d..1891584 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -65,3 +65,4 @@ after_test: Add-AppveyorTest "Violation of Rule $($codeAnalysisError.CheckId): $($codeAnalysisError.TypeName) Line Number: $($issueNode.Line)" -Outcome Failed -FileName "$($issueNode.Path)\$($codeAnalysisError.Issue.File)" -ErrorMessage $($issueNode.InnerXml); } Push-AppveyorArtifact fxcop.out.xml; +- cmd: cd bin && bench diff --git a/bench/mvt-bench-fixtures b/bench/mvt-bench-fixtures new file mode 160000 index 0000000..77758e8 --- /dev/null +++ b/bench/mvt-bench-fixtures @@ -0,0 +1 @@ +Subproject commit 77758e86720801c5fb7db7a2c578bfe137eb8872 diff --git a/src/Bench/Bench.csproj b/src/Bench/Bench.csproj new file mode 100644 index 0000000..fc38081 --- /dev/null +++ b/src/Bench/Bench.csproj @@ -0,0 +1,66 @@ + + + + + Debug + AnyCPU + {5FA56C72-348A-4B52-980C-EA8287E66422} + Exe + Properties + Bench + Bench + v4.6 + 512 + + + + AnyCPU + true + full + false + ..\..\bin\ + DEBUG;TRACE + prompt + 4 + false + + + AnyCPU + pdbonly + true + ..\..\bin\ + TRACE + prompt + 4 + false + + + + + + + + + + + + + + + + {4656b308-1492-4a22-a73e-06bf6aa858f2} + VectorTileReader + + + + + + + + \ No newline at end of file diff --git a/src/Bench/Program.cs b/src/Bench/Program.cs new file mode 100644 index 0000000..a96ccd5 --- /dev/null +++ b/src/Bench/Program.cs @@ -0,0 +1,140 @@ +using Mapbox.VectorTile; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; + +namespace ProfileDecoding +{ + class Program + { + static int Main(string[] args) + { + + //ul 14/4680/6260 + //lr 14/4693/6274 + ulong zoom = 14; + ulong minCol = 4680; + ulong minRow = 6260; + ulong maxCol = 4693; + ulong maxRow = 6274; + + string fixturePath = Path.Combine("..", "bench", "mvt-bench-fixtures", "fixtures"); + if (!Directory.Exists(fixturePath)) + { + Console.Error.WriteLine("fixture directory not found: [{0}]", fixturePath); + return 1; + } + + ulong nrOfTiles = (maxCol - minCol + 1) * (maxRow - minRow + 1); + List tiles = new List((int)nrOfTiles); + + //https://a.tiles.mapbox.com/v4/mapbox.mapbox-terrain-v2,mapbox.mapbox-streets-v7/13/2343/3133.vector.pbf?access_token= + using (GZipWebClient wc = new GZipWebClient()) + { + for (ulong col = minCol; col <= maxCol; col++) + { + for (ulong row = minRow; row <= maxRow; row++) + { + string fileName = string.Format("{0}-{1}-{2}.mvt", zoom, col, row); + fileName = Path.Combine(fixturePath, fileName); + if (!File.Exists(fileName)) + { + Console.Error.WriteLine("fixture mvt not found: [{0}]", fileName); + return 1; + } else + { + tiles.Add(new TileData() { + zoom = zoom, + col = col, + row = row, + pbf = File.ReadAllBytes(fileName) + }); + } + } + } + } + + Stopwatch stopWatch = new Stopwatch(); + List elapsed = new List(); + + for (int i = 0; i <= 100; i++) + { + Console.Write("."); + stopWatch.Start(); + foreach (var tile in tiles) + { + VectorTileReader.Decode(tile.zoom, tile.col, tile.row, tile.pbf); + } + stopWatch.Stop(); + //skip first run + if (i != 0) + { + elapsed.Add(stopWatch.ElapsedMilliseconds); + } + stopWatch.Reset(); + } + + + Console.WriteLine( + "{0}{0}runs:{1}{0}tiles per run:{2}{0}min [ms]:{3}{0}max [ms]:{4}{0}avg [ms]:{5}{0}StdDev:{6:0.00}{0}overall [ms]:{7}", + Environment.NewLine, + elapsed.Count, + tiles.Count, + elapsed.Min(), + elapsed.Max(), + elapsed.Average(), + StdDev(elapsed), + elapsed.Sum() + ); + + + return 0; + } + + + private static double StdDev(List values) + { + double ret = 0; + int count = values.Count(); + if (count > 1) + { + //Compute the Average + double avg = values.Average(); + + //Perform the Sum of (value-avg)^2 + double sum = values.Sum(d => (d - avg) * (d - avg)); + + //Put it all together + ret = Math.Sqrt(sum / count); + } + return ret; + } + + + } + + + public struct TileData + { + public ulong zoom; + public ulong col; + public ulong row; + public byte[] pbf; + } + + + public class GZipWebClient : WebClient + { + protected override WebRequest GetWebRequest(Uri address) + { + HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address); + request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; + return request; + } + } + +} diff --git a/src/Bench/Properties/AssemblyInfo.cs b/src/Bench/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..c5341ea --- /dev/null +++ b/src/Bench/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ProfileDecoding")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ProfileDecoding")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("5fa56c72-348a-4b52-980c-ea8287e66422")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/Bench/app.config b/src/Bench/app.config new file mode 100644 index 0000000..b45f31e --- /dev/null +++ b/src/Bench/app.config @@ -0,0 +1,3 @@ + + + diff --git a/src/DemoConsoleApp/App.config b/src/DemoConsoleApp/App.config index 8d9f953..156c225 100644 --- a/src/DemoConsoleApp/App.config +++ b/src/DemoConsoleApp/App.config @@ -2,5 +2,5 @@ - + diff --git a/src/DemoConsoleApp/DemoConsoleApp.csproj b/src/DemoConsoleApp/DemoConsoleApp.csproj index 3e6e1c1..2b9d1c8 100644 --- a/src/DemoConsoleApp/DemoConsoleApp.csproj +++ b/src/DemoConsoleApp/DemoConsoleApp.csproj @@ -9,7 +9,7 @@ Properties DemoConsoleApp DemoConsoleApp - v4.5.2 + v4.6 512 true publish\ diff --git a/src/Geometry/DecodeGeometry.cs b/src/Geometry/DecodeGeometry.cs index 3958074..3949907 100644 --- a/src/Geometry/DecodeGeometry.cs +++ b/src/Geometry/DecodeGeometry.cs @@ -37,7 +37,7 @@ ulong extent , ulong tileColumn , ulong tileRow , GeomType geomType - , List geometry + , List geometry ) { @@ -67,7 +67,8 @@ ulong extent geomOut.Add(geomTmp); geomTmp = new List(); } - geomTmp.Add(new Point2d() { X = cursorX, Y = cursorY }); + Point2d pntTmp = new Point2d(cursorX, cursorY); + geomTmp.Add(pntTmp); } } if (cmd == Commands.ClosePath) @@ -91,11 +92,10 @@ ulong extent private static Point2d zigzagDecode(long x, long y) { - return new Point2d() - { - X = ((x >> 1) ^ (-(x & 1))), - Y = ((y >> 1) ^ (-(y & 1))) - }; + return new Point2d( + ((x >> 1) ^ (-(x & 1))), + ((y >> 1) ^ (-(y & 1))) + ); } } } diff --git a/src/Geometry/Geometry.cs b/src/Geometry/Geometry.cs index 75847f3..205f00d 100644 --- a/src/Geometry/Geometry.cs +++ b/src/Geometry/Geometry.cs @@ -16,7 +16,7 @@ public enum GeomType POLYGON = 3 } - public class LatLng + public struct LatLng { public double Lat { get; set; } public double Lng { get; set; } @@ -31,9 +31,15 @@ public override string ToString() } } - public class Point2d + public struct Point2d { + public Point2d(long x, long y) + { + X = x; + Y = y; + } + public long X { get; set; } public long Y { get; set; } diff --git a/src/Geometry/Geometry.csproj b/src/Geometry/Geometry.csproj index a1ef56b..9d39de1 100644 --- a/src/Geometry/Geometry.csproj +++ b/src/Geometry/Geometry.csproj @@ -21,6 +21,7 @@ x64 prompt MinimumRecommendedRules.ruleset + false ..\..\bin\ @@ -30,6 +31,7 @@ x64 prompt MinimumRecommendedRules.ruleset + false true @@ -39,6 +41,7 @@ AnyCPU prompt MinimumRecommendedRules.ruleset + false ..\..\bin\ @@ -48,6 +51,7 @@ AnyCPU prompt MinimumRecommendedRules.ruleset + false diff --git a/src/PbfReader/PbfReader.cs b/src/PbfReader/PbfReader.cs index 25e93e9..c6e5cee 100644 --- a/src/PbfReader/PbfReader.cs +++ b/src/PbfReader/PbfReader.cs @@ -71,15 +71,15 @@ public byte[] View() } - public List GetPackedUnit32() + public List GetPackedUnit32() { - List values = new List(); + List values = new List(200); ulong sizeInByte = Varint(); ulong end = Pos + sizeInByte; while (Pos < end) { ulong val = Varint(); - values.Add((UInt32)val); + values.Add((uint)val); } return values; } @@ -153,9 +153,9 @@ public void SkipVarint() public void SkipBytes(ulong skip) { - string msg = string.Format(NumberFormatInfo.InvariantInfo, "[SkipBytes()] skip:{0} pos:{1} len:{2}", skip, Pos, _length); if (Pos + skip > _length) { + string msg = string.Format(NumberFormatInfo.InvariantInfo, "[SkipBytes()] skip:{0} pos:{1} len:{2}", skip, Pos, _length); throw new Exception(msg); } Pos += skip; diff --git a/src/PbfReader/PbfReader.csproj b/src/PbfReader/PbfReader.csproj index 7e7e241..343b098 100644 --- a/src/PbfReader/PbfReader.csproj +++ b/src/PbfReader/PbfReader.csproj @@ -21,6 +21,7 @@ x64 prompt MinimumRecommendedRules.ruleset + false ..\..\bin\ @@ -30,6 +31,7 @@ x64 prompt MinimumRecommendedRules.ruleset + false true @@ -39,6 +41,7 @@ AnyCPU prompt MinimumRecommendedRules.ruleset + false ..\..\bin\ @@ -48,6 +51,7 @@ AnyCPU prompt MinimumRecommendedRules.ruleset + false diff --git a/src/Util/Util.csproj b/src/Util/Util.csproj index c8cc061..c770770 100644 --- a/src/Util/Util.csproj +++ b/src/Util/Util.csproj @@ -11,6 +11,7 @@ Mapbox.VectorTile.Util v3.5 512 + true @@ -20,6 +21,7 @@ x64 prompt MinimumRecommendedRules.ruleset + false ..\..\bin\ @@ -29,6 +31,7 @@ x64 prompt MinimumRecommendedRules.ruleset + false true @@ -38,6 +41,7 @@ AnyCPU prompt MinimumRecommendedRules.ruleset + false ..\..\bin\ @@ -47,6 +51,7 @@ AnyCPU prompt MinimumRecommendedRules.ruleset + false diff --git a/src/VectorTileReader/VectorTileReader.cs b/src/VectorTileReader/VectorTileReader.cs index 7cfc678..18ccd1e 100644 --- a/src/VectorTileReader/VectorTileReader.cs +++ b/src/VectorTileReader/VectorTileReader.cs @@ -139,7 +139,7 @@ ulong zoom throw new Exception("feature already has a geometry"); } //get raw array of commands and coordinates - List geometry = featureReader.GetPackedUnit32(); + List geometry = featureReader.GetPackedUnit32(); //decode commands and coordinates List> geom = DecodeGeometry.GetGeometry( layer.Extent diff --git a/src/VectorTileReader/VectorTileReader.csproj b/src/VectorTileReader/VectorTileReader.csproj index 5ebe3f5..4141a51 100644 --- a/src/VectorTileReader/VectorTileReader.csproj +++ b/src/VectorTileReader/VectorTileReader.csproj @@ -21,6 +21,7 @@ x64 prompt MinimumRecommendedRules.ruleset + false ..\..\bin\ @@ -30,6 +31,7 @@ x64 prompt MinimumRecommendedRules.ruleset + false true @@ -39,6 +41,7 @@ AnyCPU prompt MinimumRecommendedRules.ruleset + false ..\..\bin\ @@ -48,6 +51,7 @@ AnyCPU prompt MinimumRecommendedRules.ruleset + false diff --git a/src/VectorTiles.Tests/TestGeometry.cs b/src/VectorTiles.Tests/TestGeometry.cs index 120c288..290960e 100644 --- a/src/VectorTiles.Tests/TestGeometry.cs +++ b/src/VectorTiles.Tests/TestGeometry.cs @@ -16,7 +16,7 @@ public void GeometryObjects() LatLng ll = new LatLng() { Lng = 15, Lat = 48 }; Assert.AreEqual("48.000000/15.000000", ll.ToString(), "LatLng.ToString()"); - Point2d ptSE = new Point2d() { X = 4096, Y = 4096 }; + Point2d ptSE = new Point2d(4096, 4096); Assert.AreEqual("4096/4096", ptSE.ToString(), "Point2d.ToString()"); LatLng fromPtSE = ptSE.ToLngLat(0, 0, 0, 4096); diff --git a/src/VectorTiles.Tests/VectorTiles.Tests.csproj b/src/VectorTiles.Tests/VectorTiles.Tests.csproj index b08e694..f380c59 100644 --- a/src/VectorTiles.Tests/VectorTiles.Tests.csproj +++ b/src/VectorTiles.Tests/VectorTiles.Tests.csproj @@ -8,9 +8,10 @@ Properties VectorTiles.Tests VectorTiles.Tests - v4.5.2 + v4.6 512 {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + true