writing
This commit is contained in:
parent
f04ae39ab6
commit
cbb20635c0
@ -9,12 +9,12 @@
|
||||
% Why important, who participants, trends,
|
||||
|
||||
|
||||
Simplification of polygonal data structures is the task of reducing data points while preserving topological characteristics. The simplification often takes the form of removing points that make up the geometry. There are several solutions that tackle the problem in different ways. This thesis aims to compare and classify these solutions by various heuristics. Performance and compression rate are quantitative heuristic used. Positional, length and area errors will also be measured to quantify simplification errors. With the rising trend of moving desktop applications to the web platform also geographic information systems (GIS) have experienced the shift towards web browsers \footnote{\path{https://www.esri.com/about/newsroom/arcnews/implementing-web-gis/}}. Performance is critical in these applications. Since simplification is an important factor to performance the solutions will be tested by constructing a web application using a technology called WebAssembly.
|
||||
Simplification of polygonal data structures is the task of reducing data points while preserving topological characteristics. The simplification often takes the form of removing points that make up the geometry. There are several solutions that tackle the problem in different ways. This thesis aims to compare and classify these solutions by various heuristics. Performance and compression rate are quantitative heuristic used. Positional, length and area errors will also be measured to quantify simplification errors. With the rising trend of moving desktop applications to the web platform also geographic information systems (GIS) have experienced the shift towards web browsers \footnote{\url{https://www.esri.com/about/newsroom/arcnews/implementing-web-gis/}}. Performance is critical in these applications. Since simplification is an important factor to performance the solutions will be tested by constructing a web application using a technology called WebAssembly.
|
||||
|
||||
|
||||
\subsection{Binary instruction sets on the web platform}
|
||||
|
||||
The recent development of WebAssembly allows code written in various programming languages to be run natively in web browsers. So far JavaScript was the only native programming language on the web. The goals of WebAssembly are to define a binary instruction format as a compilation target to execute code at native speed and taking advantage of common hardware capabilities \footnote{\path{https://webassembly.org/}}. The integration into the web platform brings portability to a wide range of platforms like mobile and internet of things (IoT). The usage of this technology promises performance gains that will be tested by this thesis. The results can give conclusions to whether WebAssembly is worth a consideration for web applications with geographic computational aspects. Web GIS is an example technology that would benefit greatly of such an advancement. Thus far WebAssembly has been shipped to the stable version of the four most used browser engines \footnote{\path{https://lists.w3.org/Archives/Public/public-webassembly/2017Feb/0002.html}]}. The mainly targeted high-level languages for compilation are C and C++. Also a compiler for Rust and a TypeScript subset has been developed. It will be explored how existing implementations could easily be adopted when using a compiler.
|
||||
The recent development of WebAssembly allows code written in various programming languages to be run natively in web browsers. So far JavaScript was the only native programming language on the web. The goals of WebAssembly are to define a binary instruction format as a compilation target to execute code at native speed and taking advantage of common hardware capabilities \footnote{\url{https://webassembly.org/}}. The integration into the web platform brings portability to a wide range of platforms like mobile and internet of things (IoT). The usage of this technology promises performance gains that will be tested by this thesis. The results can give conclusions to whether WebAssembly is worth a consideration for web applications with geographic computational aspects. Web GIS is an example technology that would benefit greatly of such an advancement. Thus far WebAssembly has been shipped to the stable version of the four most used browser engines \footnote{\url{https://lists.w3.org/Archives/Public/public-webassembly/2017Feb/0002.html}]}. The mainly targeted high-level languages for compilation are C and C++. Also a compiler for Rust and a TypeScript subset has been developed. It will be explored how existing implementations could easily be adopted when using a compiler.
|
||||
|
||||
\subsection{Performance as important factor for web applications}
|
||||
|
||||
|
@ -5,9 +5,9 @@
|
||||
Here the data formats that are used through this theses will be explained.
|
||||
|
||||
|
||||
\paragraph{The JavaScript Object Notation (JSON) Data Interchange Format} was derived from the ECMAScript Programming Language Standard\footnote{\path{https://tools.ietf.org/html/rfc8259}}. It is a text format for the serialization of structured data. As a text format is suites well for the data exchange between server and client. Also it can easily be consumed by JavaScript. These characteristics are ideal for web based applications. It does however only support a limited number of data types. Four primitive ones (string, number, boolean and null) and two structured ones (objects and array). Objects are an unordered collection of name-value pairs, while arrays are simply ordered lists of values. JSON was meant as a replacement for XML as it provides a more human readable format. Through nesting complex data structures can be created.
|
||||
\paragraph{The JavaScript Object Notation (JSON) Data Interchange Format} was derived from the ECMAScript Programming Language Standard\footnote{\url{https://tools.ietf.org/html/rfc8259}}. It is a text format for the serialization of structured data. As a text format is suites well for the data exchange between server and client. Also it can easily be consumed by JavaScript. These characteristics are ideal for web based applications. It does however only support a limited number of data types. Four primitive ones (string, number, boolean and null) and two structured ones (objects and array). Objects are an unordered collection of name-value pairs, while arrays are simply ordered lists of values. JSON was meant as a replacement for XML as it provides a more human readable format. Through nesting complex data structures can be created.
|
||||
|
||||
\paragraph{The GeoJSON Format} is a geospatial data interchange format\footnote{\path{https://tools.ietf.org/html/rfc7946}}. As the name suggests it is based on JSON and deals with data representing geographic features. There are several geometry types defined to be compatible with the types in the OpenGIS Simple Features Implementation Specification for SQL\footnote{\path{https://portal.opengeospatial.org/files/?artifact_id=829}}. These are Point, MultiPoint, LineString, MultiLineString, Polygon, Multipolygon and the heterogeneous GeometryCollection. Listing \ref{lst:geojson-example} shows a simple example of a GeoJSON object with one point feature. A more complete example can be viewed in the file \path{./data/example-7946.geojson}.
|
||||
\paragraph{The GeoJSON Format} is a geospatial data interchange format\footnote{\url{https://tools.ietf.org/html/rfc7946}}. As the name suggests it is based on JSON and deals with data representing geographic features. There are several geometry types defined to be compatible with the types in the OpenGIS Simple Features Implementation Specification for SQL\footnote{\url{https://portal.opengeospatial.org/files/?artifact_id=829}}. These are Point, MultiPoint, LineString, MultiLineString, Polygon, Multipolygon and the heterogeneous GeometryCollection. Listing \ref{lst:geojson-example} shows a simple example of a GeoJSON object with one point feature. A more complete example can be viewed in the file \path{data/example-7946.geojson}.
|
||||
|
||||
\lstinputlisting[
|
||||
float=!htb,
|
||||
@ -23,12 +23,16 @@ GeoJSON is mainly used for web-based mapping. Since it is based on JSON it inhe
|
||||
|
||||
To its downsides count that a text based cannot store the geometries as efficiently as it would be possible with a binary format. Also only vector-based data types can be represented. Another disadvantage can be the strictly non-topologic approach. Every feature is completely described by one entry. However when there are features that share common components, like boundaries in neighboring polygons, these data points will be encoded twice in the GeoJSON object. On the one hand this further poses concerns about data size. On the other hand it is more difficult to execute topological analysis on the data set. Luckily there is a related data structure to tackle this problem.
|
||||
|
||||
\todo[inline]{Extract more info about topology: https://www.esri.com/news/arcuser/0401/topo.html}
|
||||
\paragraph{TopoJSON} is an extension of GeoJSON and aims to encode datastructures into a shared topology\footnote{\url{https://github.com/topojson/topojson-specification}}. It supports the same geometry types as GeoJSON. It differs in some additional properties to use and new object types like "Topology" and "GeometryCollection". Its main feature is that LineStrings, Polygons and their multiplicitary equivalents must define line segments in a common property called "arcs". The geometries themselves then reference the arcs from with they are made up. This reduces redundancy of data points. Another feature is the quantization of positions. To use it one can define a "transform" object which specifies a scale and translate point to encode all coordinates. Together with delta-encoding of position arrays one obtains integer values better suited for efficient serialization and reduced file size.
|
||||
|
||||
Other than the reduced data duplication topological formats have the benefit of topological analysis and editing. When modifying adjacent Polygons for example by simplification one would prefer TopoJSON over GeoJSON. Figure \ref{fig:topological-editing} shows what this means. When modifying the boundary of one polygon, one can create gaps or overlaps in non-topological representations. With a topological data structure however the topology will preserve. [esri]\footnote{\url{https://www.esri.com/news/arcuser/0401/topo.html}}
|
||||
|
||||
\paragraph{TopoJSON} is an extension of GeoJSON and aims to encode datastructures into a shared topology\footnote{\path{https://github.com/topojson/topojson-specification}}. It supports the same geometry types as GeoJSON. It differs in some additional properties to use and new object types like "Topology" and "GeometryCollection". Its main feature is that LineStrings, Polygons and their \todo{find better word}multiplicary equivalents must define line segments in a common property called "arcs". The geometries themselves then reference the arcs from with they are made up. This reduces redundancy of data points. Another feature is the quantization of positions. To use it one can define a "transform" object which specifies a scale and translate point to encode all coordinates. Together with delta-encoding of position arrays one obtains integer values better suited for efficient serialization and reduced file size.
|
||||
|
||||
\todo[inline]{Explain why topology-preserving shape simplification is important}
|
||||
\begin{figure}
|
||||
\centering
|
||||
\includegraphics[width=.3\linewidth]{./images/topological-editing.png}
|
||||
\label{fig:topological-editing}
|
||||
\caption{Topological editing (top) vs. Non-topological editing (bottom) [esri]}
|
||||
\end{figure}
|
||||
|
||||
\paragraph{Coordinate representation} Both GeoJSON and TopoJSON represent positions as an array of numbers. The elements depict longitude, latitude and optionally altitude in that order. For simplicity this thesis will deal with two-dimensional positions only. A polyline is described by creating an array of these positions as seen in listing \ref{lst:coordinates-array}.
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
\subsection{Polyline simplification}
|
||||
|
||||
In this chapter several algorithms for polyline simplification will be explained. For each algorithm a short summary of the routine and the runtime complexity will. At the end a comparison will be drawn to determine the method used for benchmarking.
|
||||
In this chapter several algorithms for polyline simplification will be explained. For each algorithm a short summary of the routine will be given. At the end a comparison will be drawn to determine the method in use for benchmarking.
|
||||
|
||||
%In this chapter the history behind polyline simplification is shown. Several algorithm in the chronological order of their creation will be explained. At the end comparison will be drawn to determine the method used for benchmarking.
|
||||
|
||||
@ -14,9 +14,9 @@ In this chapter several algorithms for polyline simplification will be explained
|
||||
% \label{fig:algo-np}
|
||||
%\end{figure}
|
||||
|
||||
\paragraph{The Random-point routine} is derived from the n-th point algorithm. It sections the line into parts containing n consecutive positions. From each section a random point is chosen to construnct the simplified line. \todo{O(n)}
|
||||
\paragraph{The Random-point routine} is derived from the n-th point algorithm. It sections the line into parts containing n consecutive positions. From each section a random point is chosen to construct the simplified line.
|
||||
|
||||
\paragraph{Radial distance algorithm} Another simple algorithm to reduce points clustered too closely together. The algorithm will sequentially go through the line and eliminate all points whose distance to the current key is shorter than a given tolerance limit. As soon as a point with greater distance is found, it becomes the new key. \todo{O(n)}
|
||||
\paragraph{Radial distance algorithm} Another simple algorithm to reduce points clustered too closely together. The algorithm will sequentially go through the line and eliminate all points whose distance to the current key is shorter than a given tolerance limit. As soon as a point with greater distance is found, it becomes the new key.
|
||||
|
||||
%\begin{figure}
|
||||
% \centering
|
||||
@ -26,7 +26,7 @@ In this chapter several algorithms for polyline simplification will be explained
|
||||
%\end{figure}
|
||||
|
||||
|
||||
\paragraph{Perpendicular distance algorithm} Again a tolerance limit is given. The measure to check against is the perpendicular distance of a point to the line connecting its two neighbors. All points that exceed this limit are retained. \todo{O(n)}
|
||||
\paragraph{Perpendicular distance algorithm} Again a tolerance limit is given. The measure to check against is the perpendicular distance of a point to the line connecting its two neighbors. All points that exceed this limit are retained.
|
||||
|
||||
%\begin{figure}
|
||||
% \centering
|
||||
@ -36,7 +36,9 @@ In this chapter several algorithms for polyline simplification will be explained
|
||||
%\end{figure}
|
||||
|
||||
|
||||
\paragraph{Reumann-Witkam simplification} As the name implies this algorithm was developed by Reumann and Witkam. In 1974 they described the routine that constructs a "corridor/search area" by placing two parallels line in the direction of its initial tangent. The distance from this segment is user specified. Then the successive points will be checked until a point outside of this area is found. Its predecessor becomes a key and the two points mark the new tangent for the search area. This procedure is repeated until the last point is reached. \todo{O(n)}
|
||||
\paragraph{Reumann-Witkam simplification} As the name implies this algorithm was developed by Reumann and Witkam. In 1974 they described the routine that constructs a "corridor/search area" by placing two parallel lines in the direction of its initial tangent. The distance from this segment is user specified. Then the successive points will be checked until a point outside of this area is found. Its predecessor becomes a key and the two points mark the new tangent for the search area. This procedure is repeated until the last point is reached.
|
||||
|
||||
\paragraph{Zhao-Saalfeld simplification} This routine, also called the sleeve-fitting polyline simplification, developed in 1997 is similar to the Reumann-Witkam algorithm. Its goal is to fit as many consecutive points in the search area. The corridor is however not aligned to the initial tangent but rather to the last point in the sequence. From the starting point on successors get added as long as all in-between points fit in the sleeve. If the constraint fails a new sleeve will be started from the last point in the previous section.
|
||||
|
||||
%\begin{figure}
|
||||
% \centering
|
||||
@ -46,7 +48,7 @@ In this chapter several algorithms for polyline simplification will be explained
|
||||
%\end{figure}
|
||||
|
||||
|
||||
\paragraph{The Opheim simplification} Opheim extends the Reumann-Witkam algorithm in 1982 by constraining the search area. To do that two parameters \textsf{dmin} and \textsf{dmax} are given. From the key point on the last point inside a radial distance search region defined by \textsf{dmin} is taken to form the direction of the search corridor. If there is no point inside this region the subsequent point is taken. Then the process from the Reumann-Witkam algorithm is applied with the corridor constrained to a maximum distance of \textsf{dmax}. \todo{O(n)}
|
||||
\paragraph{The Opheim simplification} Opheim extends the Reumann-Witkam algorithm in 1982 by constraining the search area. To do that two parameters \textsf{dmin} and \textsf{dmax} are given. From the key point on the last point inside a radial distance search region defined by \textsf{dmin} is taken to form the direction of the search corridor. If there is no point inside this region the subsequent point is taken. Then the process from the Reumann-Witkam algorithm is applied with the corridor constrained to a maximum distance of \textsf{dmax}.
|
||||
|
||||
%\begin{figure}
|
||||
% \centering
|
||||
@ -56,7 +58,7 @@ In this chapter several algorithms for polyline simplification will be explained
|
||||
%\end{figure}
|
||||
|
||||
|
||||
\paragraph{Lang simplification} Lang described this algorithm in 1969. The search area is defined by a specified number of points too look ahead of the key point. A line is constructed from the key point to the last point in the search area. If the perpendicular distance of all intermediate points to this line is below a tolerance limit, they will be removed and the last point is the new key. Otherwise the search area is shrunk by excluding this last point until the requirement is met or there are no more intermediate points. \todo{O(??) maybe $O(m^n)$}
|
||||
\paragraph{Lang simplification} Lang described this algorithm in 1969. The search area is defined by a specified number of points too look ahead of the key point. A line is constructed from the key point to the last point in the search area. If the perpendicular distance of all intermediate points to this line is below a tolerance limit, they will be removed and the last point is the new key. Otherwise the search area is shrunk by excluding this last point until the requirement is met or there are no more intermediate points. All the algorithms before operated on the line sequentially and have a linear time complexity. This one also operates sequentially, but one of the critics about the Lang algorithm is that it requires too much computer time (DP). The complexity of this algorithm is $\mathcal{O}(m^n)$.
|
||||
|
||||
%\begin{figure}
|
||||
% \centering
|
||||
@ -67,7 +69,7 @@ In this chapter several algorithms for polyline simplification will be explained
|
||||
|
||||
%\paragraph{Jenks simplification}
|
||||
|
||||
\paragraph{Douglas-Peucker simplification} \todo{O(n*m)}
|
||||
\paragraph{Douglas-Peucker simplification} David H. Douglas and Thomas K. Peucker developed this algorithm in 1973 as an improvement to the by then predominant Lang algorithm. It is the first global routine described here. A global routine considers the entire line for the simplification process and comes closest to imitating manual simplification techniques (clayton). The algorithm starts with constructing a line between the first point (anchor) and last point (floating point) of the feature. The perpendicular distance of all points in between those two is calculated. The intermediate point furthest away from the line will become the new floating point on the condition that its perpendicular distance is greater than the specified tolerance. Otherwise the line segment is deemed suitable to represent the whole line. In this case the floating point is considered the new anchor and the last point will serve as floating point again (DP). The worst case complexity of this algorithm is $\mathcal{O}(nm)$ with $\mathcal{O}(n\log{}m)$ being the average complexity (psimpl). The m here is the number of points in the resulting line which is not known beforehand.
|
||||
|
||||
%\begin{figure}
|
||||
% \centering
|
||||
@ -76,17 +78,16 @@ In this chapter several algorithms for polyline simplification will be explained
|
||||
% \label{fig:algo-dp}
|
||||
%\end{figure}
|
||||
|
||||
%\paragraph{with reduction parameter} \todo{O(n*m)}
|
||||
|
||||
\paragraph{with reduction parameter} \todo{O(n*m)}
|
||||
\paragraph{Visvalingam-Whyatt simplification} This is another global point routine. It was developed in 1993 (VW). Visvalingam and Wyatt use a area-based method to rank the points by their significance. To do that the "effective area" of each point has to be calculated. This is the area the point spans up with its adjoining points (Shi). Then the points with the least effective area get iteratively eliminated, and its neighbors effective area recalculated, until there are only two points left. At each elimination the point gets stored in a list alongside with its associated area. This is the effective area of that point or the associated area of the previous point in case the latter one is higher. This way the algorithm can be used for scale dependent and scale-independent generalizations.
|
||||
|
||||
|
||||
|
||||
\paragraph{Visvalingam-Whyatt simplification}
|
||||
|
||||
\paragraph{Zhao-Saalfeld simplification}
|
||||
|
||||
\subsubsection{Summary}
|
||||
|
||||
The algorithms shown here are most common used simplification algorithms in cartography and GIS. The usage of one algorithm stands out however. It is the Douglas-Peucker algorithm. Its complexity however is not ideal for web-based applications. The solution is to preprocess the line with the linear-time radial distance algorithm to reduce point clusters. This solution will be further discussed in section \ref{ch:simplify.js}.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,31 +1,39 @@
|
||||
|
||||
\subsection[Web runtimes]{Running the algorithms on the web platform}
|
||||
|
||||
JavaScript has been the only native programming language of web browsers for a long time. With the development of WebAssembly there seems to be an alternative on its way with high promises. This technology and the benefits and drawbacks to it will be explained in this chapter. It will be used to execute the algorithms under inspection in this thesis.
|
||||
JavaScript has been the only native programming language of web browsers for a long time. With the development of WebAssembly there seems to be an alternative on its way. This technology, its benefits and drawbacks, will be explained in this chapter.
|
||||
|
||||
|
||||
\subsubsection{Introduction to Webassembly}
|
||||
|
||||
WebAssembly is designed by engineers from the four major browser vendors (Mozilla, Google, Apple, Microsoft). It is a portable low-level bytecode designed as target for compilationof high-level languages. By being an abstraction over modern hardware it is language-, hardware-, and platform-independent. It is intended to be run in a stack-based virtual machine. This way it is not restrained to the Web platform or a JavaScript environment. Some key concepts are the structuring into modules with exported and imported definitions and the linear memory model. Memory is represented as a large array of bytes that can be dynamically grown. Security is ensured by the linear memory being disjoint from code space, the execution stack and the engine's data structures. Another feature of WebAssembly is the possibility of streaming compilation and the parallelization of compilation processes. \footnote{\path{https://people.mpi-sws.org/~rossberg/papers/Haas,\%20Rossberg,
|
||||
WebAssembly started in April 2015 with an W3C Community Group\footnote{\url{https://www.w3.org/community/webassembly/}} and is designed by engineers from the four major browser vendors (Mozilla, Google, Apple and Microsoft). It is a portable low-level bytecode designed as target for compilationof high-level languages. By being an abstraction over modern hardware it is language-, hardware-, and platform-independent. It is intended to be run in a stack-based virtual machine. This way it is not restrained to the Web platform or a JavaScript environment. Some key concepts are the structuring into modules with exported and imported definitions and the linear memory model. Memory is represented as a large array of bytes that can be dynamically grown. Security is ensured by the linear memory being disjoint from code space, the execution stack and the engine's data structures. Another feature of WebAssembly is the possibility of streaming compilation and the parallelization of compilation processes. \footnote{\url{https://people.mpi-sws.org/~rossberg/papers/Haas,\%20Rossberg,
|
||||
\%20Schuff,\%20Titzer,\%20Gohman,\%20Wagner,\%20Zakai,\%20Bastien,\%20Holman\%20-\%20Bringing\%20the\%20Web\%20up\%20to\%20Speed\%20with\%20WebAssembly.pdf}}
|
||||
|
||||
\paragraph{Benefits of WebAssembly}
|
||||
|
||||
The goals of WebAssembly have been well defined. It's semantics are intended to be safe and fast to execute and bring portability by language-, hardware- and platform-independence. Furthermore it should be deterministic and have simple interoperability with the web platform. For its representation the following goals are declared. It shall be compact and easy to decode, validate and compile. Parallelization and streamable compilation are also mentioned.
|
||||
|
||||
These goals are not specific to WebAssembly. They can be seen as properties that a low-level compilation target for the web should have. In fact there have been previous attempts to run low-level code on the web. Examples are Microsoft's ActiveX, Native Client (NaCl) and Emscripten each having issues complying with the goals. Java and Flash are examples for managed runtime plugins. Their usage is declining however not at least due to falling short on the goals mentioned above.
|
||||
|
||||
It is often stated that WebAssembly can bring performance benefits. It makes sense that statically typed machine code beats scripting languages performance wise. It has to be observed however if the overhead of switching contexts will neglect this performance gain. JavaScript has made a lot of performance improvements over the past years. Not at least Googles development on the V8 engine has brought JavaScript to an acceptable speed for extensive calculations. The engine observes the execution of running javaScript code and will perform optimizations that can be compared to optimizations of compilers.
|
||||
|
||||
The JavaScript ecosystem has rapidly evolved the past years. Thanks to package managers like bower, npm and yarn it is simple to pull code from external sources into ones codebase. Initially thought for server sided JavaScript execution the ecosystem has found its way into front-end development via module bundlers like browserify, webpack and rollup. In course of this growth many algorithms and implementations have been ported to JavaScript for use on the web. With WebAssembly this ecosystem can be broadened even further. By lifting the language barrier existing work of many more programmers can be reused on the web. Whole libraries exclusive for native development could be imported by a few simple tweaks. Codecs not supported by browsers can be made available for use in any browser supporting WebAssembly. One example could be the promising AV1 video codec. In this these the C++ library psimpl will be utilized to bring polyline simplification to the web. This library already implements various algorithms for this task. It will be further introduced in chapter \ref{ch:psimpl}.
|
||||
The JavaScript ecosystem has rapidly evolved the past years. Thanks to package managers like bower, npm and yarn it is simple to pull code from external sources into ones codebase. Initially thought for server sided JavaScript execution the ecosystem has found its way into front-end development via module bundlers like browserify, webpack and rollup. In course of this growth many algorithms and implementations have been ported to JavaScript for use on the web. With WebAssembly this ecosystem can be broadened even further. By lifting the language barrier existing work of many more programmers can be reused on the web. Whole libraries exclusive for native development could be imported by a few simple tweaks. Codecs not supported by browsers can be made available for use in any browser supporting WebAssembly. One example could be the promising AV1 video codec.
|
||||
|
||||
\paragraph{Existing compilers}
|
||||
% In this these the C++ library psimpl will be utilized to bring polyline simplification to the web. This library already implements various algorithms for this task. It will be further introduced in chapter \ref{ch:psimpl}.
|
||||
|
||||
\todo[inline]{emscripten}
|
||||
\todo[inline]{assemblyscript}
|
||||
\todo[inline]{rust}
|
||||
\paragraph{The Emscripten toolchain}
|
||||
|
||||
\paragraph{Technical hurdles}
|
||||
There are various compilers with WebAssembly as compilation target. In this thesis the Emscripten toolchain is used. Other notable compilers are wasm-pack\footnote{\url{https://rustwasm.github.io/}} for rust projects and AssemblyScript \footnote{\url{https://github.com/AssemblyScript/assemblyscript}} for a TypeScript subset. This latter compiler is particularly interesting as TypeScript, itself a superset of JavaScript, is a popular choice among web developers. This reduces the friction for WebAssembly integration as it is not necessary to learn a new language.
|
||||
|
||||
\todo[inline]{Managing memory}
|
||||
\todo[inline]{passing arrays}
|
||||
Emscripten started with the goal to compile unmodified C and C++ applications to JavaScript. They did this by acting as a compiler backend to LLVM assembly. High level languages compile through a frontend into the LLVM intermediate representation. Well known frontends are Clang and LLVM-GCC. From there it gets passed through a backend to generate the architecture specific machine code. Emscripten hooks in here to generate asm.js, a performant JavaScript subset. In figure \ref{fig:emscripten-chain} one such example chain can be seen. On the left is the original C code which sums up numbers from 1 to 100. The resulting LLVM assembly can be seen in the middle. It is definitely more verbose, but easier to work on for the backend compiler. Notable are the allocation instructions, the labeled code blocks and code flow moves. The JavaScript representation on the right is the nearly one to one translation of the LLVM assembly. The branching is done via a switch-in-for loop, memory is implemented by a JavaScript array named HEAP and LLVM assembly functions calls become normal JavaScript function calls like \textsf{\_printf()}. Through optimizations the code becomes more compact and only then performant. [zakai]
|
||||
|
||||
\begin{figure}
|
||||
\centering
|
||||
\includegraphics[width=.3\linewidth]{./images/emscripten-c.png}
|
||||
\includegraphics[width=.3\linewidth]{./images/emscripten-llvm.png}
|
||||
\includegraphics[width=.3\linewidth]{./images/emscripten-js.png}
|
||||
\caption{Example code when compiling a C program (left) to asm.js (right) through LLVM bytecode (middle) without optimizations. [zakai]}
|
||||
\label{fig:emscripten-chain}
|
||||
\end{figure}
|
||||
|
||||
It is in fact this project that inspired the creation of WebAssembly. It was even called the "natural evolution of asm.js"\footnote{\url{https://groups.google.com/forum/\#!topic/emscripten-discuss/k-egXO7AkJY/discussion}}. As of May 2018 Emscripten changed its default output to WebAssembly\footnote{\url{https://github.com/emscripten-core/emscripten/pull/6419}} while still supporting asm.js. Currently the default backend named \textsf{fastcomp} generates the WebAssembly bytecode from asm.js. A new backend however is about to take its place that compiles directly from LLVM\footnote{\url{https://v8.dev/blog/emscripten-llvm-wasm}}.
|
||||
|
||||
The compiler is only one part of the Emscripten toolchain. Part of that are various APIs, for example for file system emulation or network calls, and tools like the compiler mentioned.
|
||||
|
@ -5,10 +5,10 @@
|
||||
In this chapter I will explain the approach to improve the performance of a simplification algorithm in a web browser via WebAssembly. The go-to library for this kind of operation is Simplify.js. It is the JavaScript implementation of the Douglas-Peucker algorithm with optional radial distance preprocessing. The library will be rebuilt in the C programming language and compiled to WebAssembly with Emscripten. A web page is built to produce benchmarking insights to compare the two approaches performance wise.
|
||||
|
||||
\subsection{State of the art: Simplify.js}
|
||||
\label{sec:simplify.js}
|
||||
\label{ch:simplify.js}
|
||||
% Simplify.JS + turf
|
||||
|
||||
Simplify.js calls itself a "tiny high-performance JavaScript polyline simplification library"\footnote{\path{https://mourner.giformthub.io/simplify-js/}}. It was extracted from Leaflet, the "leading open-source JavaScript library for mobile-friendly interactive maps"\footnote{\path{https://leafletjs.com/}}. Due to its usage in leaflet and Turf.js, a geospatial analysis library, it is the most common used library for polyline simplification. The library itself currently has 20,066 weekly downloads while the Turf.js derivate @turf/simplify has 30,389. Turf.js maintains an unmodified fork of the library in its own repository. \todo{leaflet downloads}
|
||||
Simplify.js calls itself a "tiny high-performance JavaScript polyline simplification library"\footnote{\url{https://mourner.giformthub.io/simplify-js/}}. It was extracted from Leaflet, the "leading open-source JavaScript library for mobile-friendly interactive maps"\footnote{\url{https://leafletjs.com/}}. Due to its usage in leaflet and Turf.js, a geospatial analysis library, it is the most common used library for polyline simplification. The library itself currently has 20,066 weekly downloads while the Turf.js derivate @turf/simplify has 30,389. Turf.js maintains an unmodified fork of the library in its own repository. \todo{leaflet downloads}
|
||||
|
||||
The Douglas-Peucker algorithm is implemented with an optional radial distance preprocessing routine. This preprocessing trades performance for quality. Thus the mode for disabling this routine is called highest quality.
|
||||
|
||||
@ -73,7 +73,7 @@ caption=My Caption,
|
||||
label=lst:simplify-wasm-emscripten-module
|
||||
]{../lib/simplify-wasm/index.js}
|
||||
|
||||
\paragraph {Storing coordinates} into the module memory is done in the function \texttt{storeCoords}. Emscripten offers multiple views on the module memory. These correspond to the available WebAssembly data types (e.g. HEAP8, HEAPU8, HEAPF32, HEAPF64, ...)\footnote{\path{https://emscripten.org/docs/api_reference/preamble.js.html#type-accessors-for-the-memory-model}}. As Javascript numbers are always represented as a double-precision 64-bit binary\footnote{\path{https://www.ecma-international.org/ecma-262/6.0/#sec-4.3.20}} (IEEE 754-2008) the HEAP64-view is the way to go to not lose precision. Accordingly the datatype double is used in C to work with the data. Listing \ref{lst:wasm-util-store-coords} shows the transfer of coordinates into the module memory. In line 3 the memory is allocated using the exported \texttt{malloc}-function. A JavaScript TypedArray is used for accessing the buffer such that the loop for storing the values (lines 5 - 8) is trivial.
|
||||
\paragraph {Storing coordinates} into the module memory is done in the function \texttt{storeCoords}. Emscripten offers multiple views on the module memory. These correspond to the available WebAssembly data types (e.g. HEAP8, HEAPU8, HEAPF32, HEAPF64, ...)\footnote{\url{https://emscripten.org/docs/api_reference/preamble.js.html\#type-accessors-for-the-memory-model}}. As Javascript numbers are always represented as a double-precision 64-bit binary\footnote{\url{https://www.ecma-international.org/ecma-262/6.0/\#sec-4.3.20}} (IEEE 754-2008) the HEAP64-view is the way to go to not lose precision. Accordingly the datatype double is used in C to work with the data. Listing \ref{lst:wasm-util-store-coords} shows the transfer of coordinates into the module memory. In line 3 the memory is allocated using the exported \texttt{malloc}-function. A JavaScript TypedArray is used for accessing the buffer such that the loop for storing the values (lines 5 - 8) is trivial.
|
||||
|
||||
\lstinputlisting[
|
||||
float=tbph,
|
||||
@ -83,8 +83,6 @@ caption=The storeCoords function,
|
||||
label=lst:wasm-util-store-coords
|
||||
]{../lib/wasm-util/coordinates.js}
|
||||
|
||||
\todo{programming: Check for coords length $<$ 2}
|
||||
|
||||
\paragraph{To read the result} back from memory we have to look at how the simplification will be returned in the C code. Listing \ref{lst:simplify-wasm-entrypoint} shows the entry point for the C code. This is the function that gets called from JavaScript. As expected arrays are represented as pointers with corresponding length. The first block of code (line 2 - 6) is only meant for declaring needed variables. Lines 8 to 12 mark the radial distance preprocessing. The result of this simplification is stored in an auxiliary array named \texttt{resultRdDistance}. In this case \texttt{points} will have to point to the new array and the length is adjusted. Finally the Douglas-Peucker procedure is invoked after reserving enough memory. The auxiliary array can be freed afterwards. The problem now is to return the result pointer and the array length back to the calling code. \todo{Fact check. evtl unsigned}The fact that pointers in Emscripten are represented by an integer will be exploited to return a fixed size array of two containing the values. A hacky solution but it works. We can now look back at how the JavaScript code reads the result.
|
||||
|
||||
\lstinputlisting[
|
||||
@ -118,7 +116,7 @@ For the WebAssembly solution there are two files required to work with it. The w
|
||||
|
||||
File size was not the main priority when producing the WebAssembly solution. There are ways to further shrink the size of the wasm bytecode. As of now it contains the logic of the library but also necessary functionality from the C standard library. These were added by Emscripten automatically. The bloat comes from using the memory management functions malloc and free. If the goal was to reduce the file size, one would have to get along without memory management at all. This would even be possible in this case as the simplification process is a self-contained process and the module has no other usage. The input size is known beforehand so instead of creating reserved memory one could just append the result in memory at the location directly after the input feature. The function would merely need to return the result size. After the call is finished and the result is read by JavaScript the memory is not needed any more. A test build was made that renounced from memory management. The size of the wasm bytecode shrunk to 507 byte and the glue code to 2.8KB. By using vanilla JavaScript API one could even ditch the glue code altogether\footnote{\url{https://developers.google.com/web/updates/2019/02/hotpath-with-wasm}}.
|
||||
|
||||
For simplicity the memory management was left in as the optimizations would require more careful engineering to ensure correct functionality. The example above shows however the there is enormous potential to cut the size. Even file sizes below the JavaScript original are possible.
|
||||
For simplicity the memory management was left in as the optimizations would require more careful engineering to ensure correct functionality. The example above shows however that there is enormous potential to cut the size. Even file sizes below the JavaScript original are possible.
|
||||
|
||||
|
||||
\subsection{The implementation of a web framework}
|
||||
@ -153,9 +151,9 @@ In the upper right corner the different Use-Cases are listed. These cases implem
|
||||
\end{itemize}
|
||||
|
||||
\subsubsection{The different benchmark types}
|
||||
On the bottom the different types of Benchmarks implemented can be seen. They all implement the abstract \texttt{measure} function to return the mean time to run a function specified in the given BenchmarkCase. The \texttt{IterationsBenchmark} runs the function a specified number of times, while the \texttt{OpsPerTimeBenchmark} always runs a certain amount of milliseconds to tun as much iterations as possible. Both methods got their benefits and drawbacks. Using the iterations approach one cannot determine the time the benchmark runs beforehand. With fast devices and a small number of iterations one can even fall in the trap of the duration falling under the accuracy of the timer used. Those results would be unusable of course. It is however a very fast way of determining the speed of a function. And it holds valuable for getting a first approximation of how the algorithms perform over the span of datapoints. The second type, the operations per time benchmark, seems to overcome this problem. It is however prune to garbage collection, engine optimizations and other background processes. \footnote{\path{https://calendar.perfplanet.com/2010/bulletproof-javascript-benchmarks/}}
|
||||
On the bottom the different types of Benchmarks implemented can be seen. They all implement the abstract \texttt{measure} function to return the mean time to run a function specified in the given BenchmarkCase. The \texttt{IterationsBenchmark} runs the function a specified number of times, while the \texttt{OpsPerTimeBenchmark} always runs a certain amount of milliseconds to tun as much iterations as possible. Both methods got their benefits and drawbacks. Using the iterations approach one cannot determine the time the benchmark runs beforehand. With fast devices and a small number of iterations one can even fall in the trap of the duration falling under the accuracy of the timer used. Those results would be unusable of course. It is however a very fast way of determining the speed of a function. And it holds valuable for getting a first approximation of how the algorithms perform over the span of datapoints. The second type, the operations per time benchmark, seems to overcome this problem. It is however prune to garbage collection, engine optimizations and other background processes. \footnote{\url{https://calendar.perfplanet.com/2010/bulletproof-javascript-benchmarks/}}
|
||||
|
||||
Benchmark.js combines these approaches. In a first step it approximates the runtime in a few cycles. From this value it calculates the number of iterations to reach an uncertainty of at most 1\%. Then the samples are gathered. \todo{more about Benchmark.js}\footnote{\path{http://monsur.hossa.in/2012/12/11/benchmarkjs.html}}
|
||||
Benchmark.js combines these approaches. In a first step it approximates the runtime in a few cycles. From this value it calculates the number of iterations to reach an uncertainty of at most 1\%. Then the samples are gathered. \todo{more about Benchmark.js}\footnote{\url{http://monsur.hossa.in/2012/12/11/benchmarkjs.html}}
|
||||
|
||||
\subsubsection{The benchmark suite}
|
||||
For running multiple benchmarks the class \texttt{BenchmarkSuite} was created. It takes a list of BenchmarkCases and runs them through a BenchmarkType. The Suite manages starting, pausing and stopping of going through list. It updates the statistics gathered on each cycle. By injecting an onCycle method, the \texttt{App} component can give live feedback about the progress.
|
||||
|
@ -4,14 +4,11 @@ In this chapter the results are presented. There were a multitude of tests to ma
|
||||
|
||||
\todo[inline]{describe website for results}
|
||||
|
||||
Each section in this chapter describes a set of benchmarks run on the same system. A table in the beginning will indicate the problem dimensions chosen to inspect. After a description of the system and a short summary of the case the results will be presented in the form of graphs. Those are the graphs produced from the application described in chapter \ref{ch:benchmark-app}
|
||||
Each section in this chapter describes a set of benchmarks run on the same system. A table in the beginning will indicate the problem dimensions chosen to inspect. After a description of the system and a short summary of the case the results will be presented in the form of graphs. Those are the graphs produced from the application described in chapter \ref{ch:benchmark-app}. Here the results will only be briefly described. A further analysis will follow in the next chapter.
|
||||
|
||||
|
||||
\subsection{Case 1 - Windows - wasm vs js}
|
||||
\label{ch:case1}
|
||||
\marginpar{hp pavilion}
|
||||
\marginpar{6 charts}
|
||||
\marginpar{questions: 1, 3, 5}
|
||||
|
||||
\begin{table}[htb]
|
||||
\centering
|
||||
@ -22,21 +19,32 @@ Each section in this chapter describes a set of benchmarks run on the same syste
|
||||
|
||||
At first it will be observed how the algorithms perform under different browsers. The chart to use for this is the "Simplify.js vs Simplify.wasm" chart. For that a Windows system was chosen as it allows to run benchmarks under three of the four browsers in question. The dataset is the Simplify.js example which will be simplified with and without the high quality mode.
|
||||
|
||||
The device is a \textsf{HP Pavilion x360 - 14-ba101ng}\footnote{\path{https://support.hp.com/us-en/product/hp-pavilion-14-ba100-x360-convertible-pc/16851098/model/18280360/document/c05691748}} convertible. It contains an Intel® Core™ i5-8250U Processor with 4 cores, 6MB cache. The operating system is Windows 10 and the browsers are on their newest versions with Chrome 76, Firefox 68 and Edge 44.18362.1.0.
|
||||
The device is a \textsf{HP Pavilion x360 - 14-ba101ng}\footnote{\url{https://support.hp.com/us-en/product/hp-pavilion-14-ba100-x360-convertible-pc/16851098/model/18280360/document/c05691748}} convertible. It contains an Intel® Core™ i5-8250U Processor with 4 cores, 6MB cache. The operating system is Windows 10 and the browsers are on their newest versions with Chrome 75, Firefox 68 and Edge 44.18362.1.0.
|
||||
|
||||
|
||||
\input{./results-benchmark/win_ffox_simplify_vs_false.tex}
|
||||
\input{./results-benchmark/win_ffox_simplify_vs_true.tex}
|
||||
|
||||
The first two graphs (figure \ref{fig:win_ffox_simplify_vs_false} and \ref{fig:win_ffox_simplify_vs_true}) show the results for the Firefox browser. Here and in all subsequent charts of this chapter the red line indicates the performance of Simplify.wasm, the blue line represents Simplify.js and the green line its alternative that operates on coordinates as nested arrays. The gray line represents the number of positions that remain in the simplified polyline.
|
||||
|
||||
Simplify.js run without the high quality mode per default. Here at the smallest tolerance chosen the WebAssembly solution is the fastest method. It is overtaken immediately by the original JavaScript implementation where it continues to be the fastest one of the three methods. The alternative is slowest in every case.
|
||||
|
||||
In the case of the high quality mode enabled however the original and the WebAssembly solution switch places. The Simplify.js alternative clearly separates itself by being much slower than the other two. It does however have a steeper curve as the original and the WebAssembly solution have pretty consistent performance through the whole tolerance range.
|
||||
|
||||
\input{./results-benchmark/win_chro_simplify_vs_false.tex}
|
||||
\input{./results-benchmark/win_ffox_simplify_vs_false.tex}
|
||||
\input{./results-benchmark/win_edge_simplify_vs_false.tex}
|
||||
\input{./results-benchmark/win_chro_simplify_vs_true.tex}
|
||||
\input{./results-benchmark/win_ffox_simplify_vs_true.tex}
|
||||
|
||||
Figure \ref{fig:win_chro_simplify_vs_false} and \ref{fig:win_chro_simplify_vs_true} show the results under Chrome for the same setting. Here the performance seem to be switched around with the original being the slowest method in both cases. This version has however very inconsistent results. There is no clear curvature which indicates for some outside influence to the results. Either there is a flaw in the implementation or a special case of engine optimization was hit.
|
||||
|
||||
Without high quality mode the Simplify.wasm gets overtaken by the Simplify.js alternative at 0.4 tolerance. From there on the WebAssembly solution stagnates while the JavaScript one continues to get faster. With high quality enabled the performance gain of WebAssembly is more clear then in Firefox. Here the Simplify.js alternative is the second fastest followed by its original.
|
||||
|
||||
\input{./results-benchmark/win_edge_simplify_vs_false.tex}
|
||||
\input{./results-benchmark/win_edge_simplify_vs_true.tex}
|
||||
|
||||
Interestingly in the Edge browser the two JavaScript algorithms perform more alike when high quality disabled. As can be seen in figure \ref{fig:win_edge_simplify_vs_false} The turning point where WebAssembly is not the fastest is at around 0.45 to 0.6. When turning high quality on the graph in figure \ref{fig:win_edge_simplify_vs_true} resembles the chart from Chrome only with more consistent results for the original implementation.
|
||||
|
||||
\subsection{Case 2 - Windows - wasm runtime analysis}
|
||||
\label{ch:case2}
|
||||
\marginpar{hp pavilion}
|
||||
\marginpar{2 charts}
|
||||
\marginpar{questions: 2, 3, 5}
|
||||
\todo{maybe add ffox}
|
||||
|
||||
\begin{table}[htb]
|
||||
\centering
|
||||
@ -51,13 +59,14 @@ For this case the same device as in the former case is used. To compare the resu
|
||||
\input{./results-benchmark/win_edge_simplify_stack_false.tex}
|
||||
\input{./results-benchmark/win_edge_simplify_stack_true.tex}
|
||||
|
||||
The bar charts visualize where the time is spent in the Simplify.wasm implementation. Each data point contains a stacked column to represent the proportion of time spent for each task. The blue section represents the time spent to initialize the memory, the red one the execution of the compiled WebAssembly code. At last the green part will show the time spent for getting the coordinates back in the right format.
|
||||
|
||||
Inspecting figures \ref{fig:win_edge_simplify_stack_false} and \ref{fig:win_edge_simplify_stack_true} one immediately notices that the time for spent for the memory preparation does not vary in either of the two cases. Also very little time is needed to load the result back from memory especially as the tolerance gets higher. Further analysis of that will follow in chapter \ref{ch:discussion} as mentioned.
|
||||
|
||||
In the case of high quality disabled the results show a very steep curve of the execution time. Quickly the time span for preparing the memory dominates in the process. In the second graph it can be seen that the fraction is significantly lower due to the execution time being consistently higher.
|
||||
|
||||
\subsection{Case 3 - MacBook Pro - wasm vs js}
|
||||
\label{ch:case3}
|
||||
\marginpar{MacBook Pro 15}
|
||||
\marginpar{4 charts}
|
||||
\marginpar{Chrome and FF comparable to results above}
|
||||
|
||||
A 2018 MacBook Pro 15" will be used to test the safari browser. For comparison the benchmarks will also be held under Firefox on MacOS. This time the bavarian boundary will be simplified with both preprocessing enabled and disabled.
|
||||
|
||||
\begin{table}[htb]
|
||||
\centering
|
||||
@ -66,16 +75,23 @@ A 2018 MacBook Pro 15" will be used to test the safari browser. For comparison t
|
||||
\caption{Problem dimensions of Case 3}
|
||||
\end{table}
|
||||
|
||||
\input{./results-benchmark/mac_safa_bavaria_vs_false.tex}
|
||||
A 2018 MacBook Pro 15" will be used to test the safari browser. For comparison the benchmarks will also be held under Firefox on MacOS. This time the bavarian boundary will be simplified with both preprocessing enabled and disabled.
|
||||
|
||||
\input{./results-benchmark/mac_ffox_bavaria_vs_false.tex}
|
||||
\input{./results-benchmark/mac_safa_bavaria_vs_true.tex}
|
||||
\input{./results-benchmark/mac_ffox_bavaria_vs_true.tex}
|
||||
|
||||
At first figure \ref{fig:mac_ffox_bavaria_vs_false} and \ref{fig:mac_ffox_bavaria_vs_true} show the setting under Firefox. And indeed they are comparable to the results from chapter \ref{ch:case1}. In the case of high quality disabled WebAssembly is fastest for lower tolerances. After a certain point the original is faster while the alternative comes close to WebAssembly performance but without intersection. When enabling the high quality mode the original is more close to Simplify.wasm without being faster. The JavaScript alternative is still trailing behind.
|
||||
|
||||
\input{./results-benchmark/mac_safa_bavaria_vs_false.tex}
|
||||
\input{./results-benchmark/mac_safa_bavaria_vs_true.tex}
|
||||
|
||||
The results of the Safari browser with high quality disabled (figure \ref{fig:mac_safa_bavaria_vs_false}) resembles the figure \ref{fig:win_edge_simplify_vs_false} where the Edge browser was tested. Both JavaScript versions with similar performance surpass the WebAssembly version at one point. Unlike the Edge results the original implementation is slightly ahead.
|
||||
|
||||
When turning on high quality mode the JavaScript implementations still perform alike. However Simplify.wasm is clearly faster as seen in figure \ref{fig:mac_safa_bavaria_vs_true}. Simplify.wasm performs here about twice as fast as the algorithms implemented in JavaScript. Those however have a steeper decrease as the tolerance numbers go up.
|
||||
|
||||
|
||||
\subsection{Case 4 - Ubuntu - turf.js analysis}
|
||||
\label{ch:case4}
|
||||
\marginpar{Lenovo Miix 510}
|
||||
\marginpar{4 charts}
|
||||
\marginpar{Firefox because orig simplify is faster}
|
||||
|
||||
\begin{table}[htb]
|
||||
\centering
|
||||
@ -84,11 +100,20 @@ A 2018 MacBook Pro 15" will be used to test the safari browser. For comparison t
|
||||
\caption{Problem dimensions of Case 4}
|
||||
\end{table}
|
||||
|
||||
\input{./results-benchmark/ubu_ffox_bavaria_vs_false.tex}
|
||||
\input{./results-benchmark/ubu_ffox_bavaria_jsstack_false.tex}
|
||||
|
||||
|
||||
In this case the system is a \textsf{Lenovo Miix 510} convertible with Ubuntu 19.04 as the operating system. Again the bavarian outline is used for simplification with both quality settings. It will be observed if the Turf.js implementation is reasonable. The third kind of chart is in use here, which is similar to the Simplify.wasm insights. There are also stacked bar charts used to visualize the time spans of subtasks. The results will be compared to the graphs of the Simplify.js vs. Simplify.wasm chart. As the Turf.js method only makes sense when The original Simplify.js is faster than the alternative the benchmarks are performed in the Firefox browser.
|
||||
|
||||
\input{./results-benchmark/ubu_ffox_bavaria_vs_true.tex}
|
||||
\input{./results-benchmark/ubu_ffox_bavaria_jsstack_true.tex}
|
||||
|
||||
Figure \ref{fig:ubu_ffox_bavaria_vs_true} shows how the JavaScript versions perform with high quality enabled. Here it is clear that the original version is prefereable. In figure \ref{fig:ubu_ffox_bavaria_jsstack_true} one can see the runtime of the Turf.js method. The red bar here stands for the runtime of the Simplify.js function call. The blue and green bar is the time taken for the format transformations before and after the algorithm. Again the preparation of the original data takes significantly longer than the modification of the simplified line. When the alternative implementation is so much slower than the original it is actually more performant to transform the data format. More analysis as mentioned follows in the next chapter.
|
||||
|
||||
\input{./results-benchmark/ubu_ffox_bavaria_vs_false.tex}
|
||||
\input{./results-benchmark/ubu_ffox_bavaria_jsstack_false.tex}
|
||||
|
||||
The next two figures show the case when high quality is disabled. In figure \ref{fig:ubu_ffox_bavaria_vs_false} two algorithms seem to converge. And when looking at figure \ref{fig:ubu_ffox_bavaria_jsstack_false} one can see that the data preparation gets more costly as the tolerance rises. From a tolerance of 0.0014 on the alternative Simplify.js implementation is faster than the Turf.js method.
|
||||
|
||||
\subsection{Case 5 - iPhone - mobile testing}
|
||||
\label{ch:case5}
|
||||
\marginpar{iPhone??}
|
||||
|
@ -1,4 +1,5 @@
|
||||
\section{Discussion}
|
||||
\label{ch:discussion}
|
||||
|
||||
In this section the results are interpreted. This section is structured in different questions to answer. First it will be analyzed what the browser differences are. One section will deal with the performance of the pure JavaScript implementations while the next will inspect how Simplify.wasm performs. Then further insights to the performance of the WebAssembly implementation will be given. It will be investigated how long it takes to set up the WebAssembly call and how much time is spent to actually execute the simplification routines. Next the case of Turf.js will be addressed and if its format conversions are reasonable under specific circumstances. Finally the performance of mobile devices will be evaluated.
|
||||
|
||||
@ -24,7 +25,8 @@ The variance it very low when the preprocessing is turned off through the high q
|
||||
|
||||
So for when the performance of Simplify.wasm was addressed it meant the time spent for the whole process of preparing memory to running the algorithm in wasm context to loading back the result to JavaScript. This makes sense when comparing it to the JavaScript library with the motive to replace it one for one. It does however not produce meaningful comparisons of WebAssembly performance in contrast to the native JavaScript runtime.
|
||||
|
||||
This is because until Simplify.wasm actually gets to the WebAssembly computation it will take some time to prepare the data and load it back afterwards. To see how long that is the additional chart type "Simplify.wasm runtime insights" was created. In figures \ref{fig:win_edge_simplify_stack_false} and \ref{fig:win_edge_simplify_stack_true} the results can be seen. Each data point contains a stacked column to represent the proportion of time spent for each task. The blue section represents the time spent to initialize the memory, the red one the execution of the compiled WebAssembly code. At last the green part will show the time spent for getting the coordinates back in the right format.
|
||||
\todo[inline]{Check up}
|
||||
%This is because until Simplify.wasm actually gets to the WebAssembly computation it will take some time to prepare the data and load it back afterwards. To see how long that is the additional chart type "Simplify.wasm runtime insights" was created. In figures \ref{fig:win_edge_simplify_stack_false} and \ref{fig:win_edge_simplify_stack_true} the results can be seen. Each data point contains a stacked column to represent the proportion of time spent for each task. The blue section represents the time spent to initialize the memory, the red one the execution of the compiled WebAssembly code. At last the green part will show the time spent for getting the coordinates back in the right format.
|
||||
|
||||
First the parts where JavaScript is run will be examined. There is as good as no variance in the memory initialization. This is obviously due to the fact that this step is not dependent on any other parameter than the polyline length. Initial versions of the library produced in this thesis were not as efficient in flattening the coordinate array as the final version. By replacing the built-in \texttt{Array.prototype.flat}-method with a simple for loop a good amount optimization was achieved on the JavaScript side of the Simplify.wasm process. The flat method is a rather new feature of ECMAScript and its performance might be enhanced in future browser versions. This example shows however that when writing JavaScript code one can quickly deviate from the "fast path" even when dealing with simple problems.
|
||||
|
||||
|
BIN
thesis/images/emscripten-c.png
Normal file
BIN
thesis/images/emscripten-c.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
BIN
thesis/images/emscripten-js.png
Normal file
BIN
thesis/images/emscripten-js.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
BIN
thesis/images/emscripten-llvm.png
Normal file
BIN
thesis/images/emscripten-llvm.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 39 KiB |
BIN
thesis/images/topological-editing.png
Normal file
BIN
thesis/images/topological-editing.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.3 KiB |
BIN
thesis/main.pdf
BIN
thesis/main.pdf
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user