73
Porting TomP2P to .NET Benchmarking P2P in Java and C# Christian Lüthold Frauenfeld, Switzerland Student ID: 09-714-981 Supervisor: Dr. Thomas Bocek, Andri Lareida Date of Submission: April 29, 2015 University of Zurich Department of Informatics (IFI) Binzmühlestrasse 14, CH-8050 Zurich, Switzerland ifi MASTER T HESIS Communication Systems Group, Prof. Dr. Burkhard Stiller

Porting TomP2P to .NET Benchmarking P2P in Java and C# · 2015-04-27 · Abstract This thesis documents the porting of the core functionality of the open-source TomP2P library, a

  • Upload
    others

  • View
    4

  • Download
    0

Embed Size (px)

Citation preview

Porting TomP2P to .NETBenchmarking P2P in Java and C#

Christian LütholdFrauenfeld, SwitzerlandStudent ID: 09-714-981

Supervisor: Dr. Thomas Bocek, Andri LareidaDate of Submission: April 29, 2015

University of ZurichDepartment of Informatics (IFI)Binzmühlestrasse 14, CH-8050 Zurich, Switzerland ifi

MA

ST

ER

TH

ES

IS–

Com

mun

icat

ion

Sys

tem

sG

roup

,Pro

f.D

r.B

urkh

ard

Stil

ler

Master ThesisCommunication Systems Group (CSG)Department of Informatics (IFI)University of ZurichBinzmühlestrasse 14, CH-8050 Zurich, SwitzerlandURL: http://www.csg.uzh.ch/

Abstract

This thesis documents the porting of the core functionality of the open-source TomP2Plibrary, a P2P-based high performance key-value pair storage, from Java to .NET. Theport is written in C# and inter-operable with its Java counterpart. .NET-specific con-ventions and programming methodologies are used, such as the C# language feature forasynchronous programming. The absence of third-party Java libraries, i.e., The NettyProject, requires workarounds to achieve semantically equivalent behavior in .NET. Theport’s API remains identical, developer friendly and easy to understand. Besides porting,this thesis conducts benchmarks on multiple virtual machines to compare Java and .NETwith respect to execution time and memory allocation. These benchmarks measure P2P-specific real-world scenarios, implying asynchrony, network latency and I/O-streams. Thegained results show that .NET’s Command Language Runtime (CLR) yields better resultsregarding the average execution time, especially for the first few executions of code blocks.In the long run, however, Java Virtual Machines (JVMs) produce similar results. Thedifferent memory allocation strategies for CLR and JVM implicate initially higher, butgradually steadier allocations for the CLR and initially low, but gradually exceedinglyhigh memory consumption for JVMs. When it comes to speed in network operations, bothJava and .NET achieve comparable results. For long-term networking scenarios, however,TomP2P for Java scales better in terms of memory thanks to third-party functionality notyet present in the .NET counterpart.

i

ii

Zusammenfassung

Diese Masterarbeit dokumentiert die Portierung der Kernfunktionalitat der TomP2PBibliothek, einer P2P-basierten und hochperformanten Speicherlosung fur Schlussel/Wert-paare, von Java nach .NET. Die portierte Bibliothek ist mittels C# geschrieben und mitder Java Version kompatibel. Es werden .NET-spezifische Konventionen und Program-miermethodiken angewandt, sowie Spracheigenschaften von C#, beispielsweise fur dieasynchrone Programmierung, genutzt. Aufgrund fehlender Java Module von Drittanbietern,wie dem von The Netty Projekt, sind Hilfskonstruktionen notwendig um eine semantischeAquivalenz in .NET zu erreichen. Die portierte API bleibt identisch, entwicklerfreundlichund einfach zu verstehen. Neben der Portierung fuhrt diese Masterarbeit auch Benchmarksauf mehreren Virtual Machines durch, um Java und .NET bezuglich Laufzeit und Spei-cherverbrauch zu vergleichen. Diese Benchmarks messen reale, P2P-spezifische Szenarien,welche Asynchronitat, Netzwerklatenz und Datenstrome mit einbeziehen. Die gewonnenenResultate zeigen, dass .NET’s Command Language Runtime (CLR) bessere Resultate imBezug auf die durchschnittliche Laufzeit, vor allem fur die ersten paar Ausfuhrungen vonCodeblocken, erzielt. Allerdings erreichen die Java Virtual Machines (JVMs) auf die Dauerahnliche Resultate. Die verschiedenen Strategien zur Speicherzuweisung von CLR undJVM fuhren zu einer initial hoheren, aber auf die Dauer stabileren Speicherbelegung fur dieCLR und initial tieferem, dafur mit der Zeit ubermaßig hohem Speicherkonsum fur JVMs.Was die Geschwindigkeit von Netzwerkoperationen anbelangt erreichen Java und .NETvergleichbare Resultate. Bezuglich Speicherverbrauch skaliert TomP2P fur Java jedochbesser bei langfristigen Netzwerkszenarien. Der Grund dafur sind Optimierungsfunktionenvon Drittanbietern, die in .NET noch nicht verwendet werden.

iii

iv

Acknowledgments

I would like to thank the people that enabled the realization of this master thesis. Firstof all, I want to express my deep gratitude to my supervisor, Dr. Thomas Bocek,for his competent assistance, enthusiasm and ever cooperative interaction and support.Furthermore, I sincerely thank Prof. Dr. Burkhard Stiller for the permission of this projectin context of the Communication Systems Group.

v

vi

Contents

Abstract i

Zusammenfassung iii

Acknowledgments v

1 Introduction 1

1.1 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

1.2 Description of Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

1.3 Thesis Outline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

2 Related Work 3

2.1 Java vs. C# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2.1.1 The Evolution from Java to C# . . . . . . . . . . . . . . . . . . . . 3

2.1.2 Commonalities & Differences . . . . . . . . . . . . . . . . . . . . . . 4

2.1.3 Why C#? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.2 Migration from Java to .NET . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.3 Interoperability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2.4 Benchmarking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

vii

viii CONTENTS

3 Proposed Solution 9

3.1 Layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

3.2 Interoperability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

3.2.1 Interoperability Concerns . . . . . . . . . . . . . . . . . . . . . . . 10

3.2.2 Interoperability Testing . . . . . . . . . . . . . . . . . . . . . . . . . 14

3.3 Code Equivalence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

3.3.1 TomP2P Version . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

3.3.2 Data Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

3.3.3 API Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

3.3.4 Asynchrony . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

3.4 The Netty Project Counterparts . . . . . . . . . . . . . . . . . . . . . . . . 20

3.5 Benchmark Suite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

3.5.1 Benchmarking Approach . . . . . . . . . . . . . . . . . . . . . . . . 24

3.5.2 Benchmark Procedure . . . . . . . . . . . . . . . . . . . . . . . . . 25

4 Benchmarking 27

4.1 Setup Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

4.2 Execution Time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

4.2.1 Virtual Machine Comparison . . . . . . . . . . . . . . . . . . . . . . 28

4.2.2 Warm-up Phase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

4.2.3 Local vs. Remote Networking . . . . . . . . . . . . . . . . . . . . . 30

4.3 Memory Allocation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

4.3.1 Virtual Machine Comparison . . . . . . . . . . . . . . . . . . . . . . 31

4.3.2 Initial Phase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

4.3.3 UDP vs. TCP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

5 Summary 37

5.1 Summary & Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

5.2 Future Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

CONTENTS ix

Bibliography 39

Abbreviations 43

List of Figures 43

List of Tables 45

List of Listings 47

A Mapping from Java to C# 51

A.1 Keywords & Framework Types . . . . . . . . . . . . . . . . . . . . . . . . 51

A.2 Java Futures to C# Tasks . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

B Benchmarking Script 55

C Tools, Frameworks & Languages 57

D Installation Guidelines 59

D.1 TomP2P .NET . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

D.2 Interoperability Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

D.3 Benchmark Suite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

E Contents of the CD-ROM 61

x CONTENTS

Chapter 1

Introduction

This chapter starts with the motivation, followed by a description of the objectives. Beforegoing into the proposed solution, a brief outline of this thesis is given.

1.1 Motivation

Peer-to-peer (P2P) systems are still popular and account for a large portion of Internettraffic [8]. Although most of this traffic is related to file sharing, new types of P2P applica-tions are emerging. For this reason, the availability of free software for the development ofsuch distributed applications is important. TomP2P [2] is an open-source, P2P-based highperformance key-value pair storage library that is used in many applications. They rangefrom file synchronization and sharing ([15],[32]) over video live-streaming [14] to bitcoinexchange [1].The implementation of the TomP2P library is based on Oracle’s Java technology andthus benefits from its operating system independence. Given the similarities of the JavaRuntime and Microsoft’s .NET Framework, porting the TomP2P library is feasible in thetime frame of this thesis. With a version in both Java and .NET, the size of the developercommunity, to which the TomP2P library can be exposed, increases accordingly.Thus, the goal of this thesis is the port of the existing implementation to an equivalentcounterpart for the .NET environment. Not only does the ported version exhibit theexact same functionality and behavior, it also copes with the interoperability betweenthe two platforms. Furthermore, both implementations are compared with respect toexecution time and memory allocation on different virtual machines and hardware. Insteadof performing the more common, but less informative micro benchmarking, more realisticanalyses of real-world scenarios, implying asynchrony, network latency and I/O-streams,are conducted.

1

2 CHAPTER 1. INTRODUCTION

1.2 Description of Work

The major aspect of this thesis is the porting of the software to an equivalent .NETcounterpart. The main focus is directed at the TomP2P core package, the most fundamentalpart of the library. In order to achieve this goal, the internals of the core package need to beunderstood by examining what it is doing and how it works. This process of understandingcan be done incrementally and in parallel to the porting task. This thesis starts withthe most basic module, the protocol, and proceeds with the next abstraction layer. Soas to verify the ported code, unit testing of the .NET components has to be maintained.Furthermore, tests for cross-checking the correctness of these components with the Javaimplementation have to be conducted in order to achieve interoperability between the twoplatforms. With the finished .NET port, benchmarks for several workloads are performedto compare the two implementations with respect to both execution time and memoryallocation. Any potential bottlenecks in both versions are analyzed and solutions foroptimizations are found.

1.3 Thesis Outline

After this chapter has given an insight on the motivation and the target of this thesis,Chapter 2 sheds light on related approaches. After that, the proposed solutions for all goalsare presented in Chapter 3. Besides the key aspects to be addressed when porting fromJava to C# in the context of TomP2P, the projects required for interoperability testing andbenchmark execution are explained. Chapter 4 takes up with the benchmarking results,their evaluation and interpretation for different scenarios. Finally, Chapter 5 draws theconclusion of this work and lists future work.

Chapter 2

Related Work

This chapter composes related research and development. The key areas of this thesis -each dealt with in a separate subsection - consist of the comparison of the Java and C#programming languages, the migration from the former to the latter, their interoperabilityand performance comparison.

2.1 Java vs. C#

This section is about the comparison of the Java and C# languages. Their common history,related work about commonalities and differences, as well as arguments for using C# asthe target language, are included.

2.1.1 The Evolution from Java to C#

The Java programming language, originally designed by Sun Microsystems, is aimed atenabling developers to quickly build a wide range of applications and to shorten developmenttime by freeing the programmer from worrying about several low-level plumbing issues,such as memory management and type safety concerns. It is no secret that Microsoft wasimpressed by the simplicity of Java and its force of attraction to the developer community.History shows that Microsoft in fact was using Sun Microsystems’ Java, but with itsown implementation, called Visual J++, which was introduced in 1996. Further effortsproduced the fastest JVM on the market [27] as well as the so-called Windows FoundationClasses (WCF), a set of Java classes that wrapped the Win32 API. In addition to this,Microsoft wanted to apply changes to Java to integrate it more closely with Windows (i.e.,make it inter-operate with C++ and Visual Basic). As a side-effect, such changes wouldhave broke the compliance with the Java Standard and hence Sun Microsystems suedMicrosoft in 1997 for its Java license agreement violation. Due to that, Java’s appeal toMicrosoft was lost and the company took its advances in the Java language, compiler andvirtual machine to morph them into an even more ambitious project, which, in the year2000, finally resulted in the .NET Framework. As part of this framework, the programming

3

4 CHAPTER 2. RELATED WORK

language J#, whose syntax is close to Java, was introduced. Its main purpose was to helpdevelopers migrating from Visual J++ or Java to the new .NET Framework. Later, in2002, as part and main language of the .NET Framework, C# was introduced as a modern,simple, general-purpose and object-oriented programming language. Regarding the history,it is fair to state that C# was heavily inspired and influenced by Java and thus sharesmany things in common.

2.1.2 Commonalities & Differences

Today, mainstream development has largely split into two groups. Microsoft, promotingthe .NET Framework, is in one, while other vendors backing the Java environment are inthe other. Each technology has its devotees and detractors, but both have a substantiallyinstalled base. Albeit having different backgrounds, the two competing worlds are similar.Various works can be found that discuss similarities and differences between the twolanguages. Chandra and Chandra [6], for example, present a high-level side-by-sidecomparison of identifiers, keywords, operators and data types. Although they concludethat C# bears a strong resemblance to Java, they found that there are several programmingconstructs available in the former that are not found in the latter (e.g., operator overloading,reference passing, string and unsigned integer types, etc.).Eaddy [10] shows that their resemblance goes beyond syntax and keywords, but alsoincludes common features. These, among others, include the compilation and interpretationprocesses, automatic garbage collection, single inheritance and multiple implementation,exceptions and an overall Object base type. He also notes that both languages avertcommon C++ danger zones by prohibiting uninitialized variables and avoiding pointerhandling and header files.A more in-depth comparison is done by Obasanjo [31] based on practical experience usingboth languages. Not only does he describe the concepts and language features that arealmost exactly the same, he also enlists concepts that differ either syntactically or in aminor manner while being featured by both platforms. Furthermore, he discusses andcompares features that exist in C# and have no Java counterpart and vice versa. In hisconclusion, he notes that making the choice of C# over Java is not a clearcut case ofchoosing more language features without having to make any compromises. He states thatboth are similar enough that they could be made to mirror each other without significanteffort. However, C# would have it easier than Java in that it has less to borrow from Java,whereas Java would have much to borrow from C#. With this conclusion from 2001, hiswork also notes that the true worth of a programming language lies in how quickly thelanguage evolves in order to adapt to the changing technological landscape.

Like Obasanjo’s approach, this thesis analyzes both platforms with respect to practicalexperience. In contrast to all the above, the goal is not to come up with an ultimate,language-specific comparison, but to find a project-specific mapping between the two. Thefinal map, which can be viewed in Appendix A.1, then helps to preserve the conventionduring translation from - in this case - Java to C#.

2.2. MIGRATION FROM JAVA TO .NET 5

2.1.3 Why C#?

One obvious distinction between the two platforms is that the Java environment isarchitecture-independent, while .NET is designed to be a language-independent runtime,which also is more tightly integrated with Windows. However, recent announcementsfrom Microsoft [20] declare the disclosure of .NET’s latest version by making its codeopen-source. Further news [21] introduce the .NET Core 5, a general purpose, open-sourceframework that can be used across multiple platforms including Windows, Linux and MacOS [28]. This promises to make the .NET environment to finally be architecture-neutralas well.Another advantage lies in Xamarin1, whose services allow to write native mobile applicationsfor iOS, Android and Windows out of a shared C# codebase. They claim that C# can doanything that can be done in Objective-C, Swift or Java and thus is the best language formobile application development [12].

2.2 Migration from Java to .NET

Converting existing code to a newer programming language can ease integration with otherand modern technologies, give access to a wider developer community and even lowermaintenance costs. For the Java to C# scenario, there exist many projects that havebeen translated. For example, NHibernate2 initially started as a port of the Java-basedHibernate3 project. Likewise for Spring4, Lucene5, Mina6 and JUnit7 that ended up asSpring.NET8, Lucene.NET9, Mina.NET10 and NUnit11 equivalents.For language conversion of serious, large legacy code projects, automation tools arenecessary to speed up the process and minimize formal translation errors. Back in 2003,Microsoft published a Java Language Conversion Assistant12 that automatically convertedexisting Java code to C#. However, in 2005, this service has been discontinued [26] and,as Chappell [7] explains, was clearly focused on migrating code and developers entirely tothe .NET Framework, rather than supporting ongoing Java development.El-Ramly, Eltayeb and Alla [11] present their experiment about building a Java to C#transformer called Java2C#. Under the hood, the functional rule-based TXL programminglanguage is used that automatically parses input programs described in the language bythe grammar and then successively applies transformation rules to output the transformed

1Xamarin: www.xamarin.com2NHibernate: http://nhibernate.info/3Hibernate: http://hibernate.org/4Spring: https://spring.io/5Lucene: https://lucene.apache.org/6Mina: https://mina.apache.org/7JUnit: http://junit.org/8Spring.NET: http://springframework.net/9Lucene.NET: https://lucenenet.apache.org/

10Mina.NET: https://github.com/longshine/Mina.NET11NUnit: http://www.nunit.org/12Java Language Converstion Assistant: http://www.microsoft.com/en-us/download/details.

aspx?id=14349

6 CHAPTER 2. RELATED WORK

source. These transformation rules include easy one-to-one mappings as well as indirectand challenging conversions, where clever tricks and techniques are needed when thereis no direct equivalent. Unfortunately, Java2C# works only partially as it covers onlya simple subset of the Java language. El-Ramly et al. explain that complete automaticconversion is almost impossible and manual intervention is thus required.

In contrast to the highlighted automation approach, the codebase translation of thiswork is done manually altogether. On the one hand, this is necessary due to TomP2P’snon-trivial source-code that originates from its domain complexity. On the other hand,it is advantageous because certain concepts have no equivalent counterpart, may requireanother design, have distinct dependencies or underly a different platform philosophy orconvention (e.g., asynchrony handling, socket creation, usage of external libraries, etc.).

2.3 Interoperability

One goal of the application produced by this thesis is to make it work together with theexisting software. Due to such interoperability, the communication between Java and newC# peers becomes possible although the implementation is done with different languagesand the execution takes place on unequal virtual machines.Achieving interoperability is an important issue in most distributed - including P2P -systems as has been stated by Jaimez-Gonzalez and Lucas [17]. They present Web Objectsin XML13 (WOX), a human-readable XML serializer for interoperability between anyobject-oriented languages. Concretely, they show how interoperability between Java andC# can be achieved with respect to four specified issues: data type mapping, objectrepresentation, messages and serialization.According to Citrin [9], although web services base on standards and are easy, they arenot always the ideal approach to overcome interoperability. A possible scenario comprisescalling a library from the other platform through a web service, although it resides on thesame machine. Moreover, exchanging XML through sockets to accomplish simple tasksis not optimal. Instead, Citrin advises, bridges will work much more efficiently. In fact,JNBridgePro14, a Java and .NET interoperability tool, claims to be 100 to 1000 times fasterthan web services [19]. JNBridgePro automatically generates proxy classes through whichthe remote platform communicates with the local one [18]. A similar bridging approachis javOnet15, but only enables the usage of .NET libraries in Java and not vice versa.In order to access .NET code from Java, javOnet makes use of its own reflection-stylefluent API library that translates Java operations on this API directly to a separate .NETprocess. Intel has published some research about bridging solutions [16] and explains thatbridges have a number of advantages over other interoperability approaches, includingthat these solutions evolve as platforms evolve. Future versions of Java and .NET willwork with the bridging solution as long as they remain backward compatible.Yet another approach to enable Java and .NET interoperability is provided by JeroenFrijters’ IKVM.NET 16 project, a JVM and Java class libraries implemented in .NET.

13WOX: http://woxserializer.sourceforge.net/14JNBridgePro: http://jnbridge.com/software/jnbridgepro/overview15javOnet: https://www.javonet.com/16IKVM.NET: http://www.ikvm.net/

2.4. BENCHMARKING 7

IKVM provides a way for developing .NET applications in Java by producing an executableout of any existing JVM bytecode. Furthermore, the included .NET implementation ofthe IKVM can be used as a drop-in replacement for the JVM in order to execute anybytecode.

Compared to WOX’ interoperability approach, the work described in this thesis doesnot make use of language-independent XML, but concentrates on binary encoding. Thisoriginates from TomP2P’s architecture that builds upon a binary messaging protocol thatis already optimized. The advantage lies in serialization/de-serialization speed but lackshuman-readability. Also, as described in Section 3.2.1, such binary encoding introducesplatform-dependent treatment in case interoperability is a requirement.Although the JNBridgePro toolbox could have been used to realize this project, using thisservice is bound to a pricing and a respective terms of service. Furthermore, constructingthe C# from scratch without relying on third-party solutions avoids dependency andlock-in mechanisms.The IKVM is useful when creating .NET applications with the Java language. However,this thesis is interested in having physical C# source code that runs in a CLR. Also, justletting the existing Java code run in IKVM’s JVM replacement yields far worse profilingresults compared to the original JVM and CLR. A comparison of all virtual machines isdone in Chapter 4, where the shortcomings of the IKVM are depicted evidently.

2.4 Benchmarking

Considering the Java, C# and C language, Sestoft [33] compared their numeric perfor-mances for matrix multiplication and division-intensive loops. He found no significantdifferences for the two object-oriented languages, but finds that the results can be tweakedby using the Java server VM and by writing unsafe (unmanaged) C# code.In 1999, a full-blown benchmarking suite for the comparison of large scale Java applicationshas been designed and implemented by Bull, Smith, Westhead, Henty and Davey [5]. Theirapproach involves the construction of a performance comparison framework includingmethods of benchmark instrumentation and an API. By means of different applicationsfrom a wide area of disciplines - and thus different environment stress (CPU, memory, I/O,network) - a comparison of many Java-ready virtual machines was conducted.But ahead of the realization and interpretation of benchmarks, insight into what happensduring the runtime, especially with new languages like Java and C# that run on sophisti-cated virtual-machines, is required. Boyer [4] covers some common pitfalls associated withJava code, such as time measurement resolution, code warm-up, dynamic optimizationand deoptimization, resource reclamation and dead code elimination. Furthermore, helists preparations for the system on which the benchmarks are executed. These compriseof power supply, the reduction of concurrent processes that may induce noise on the CPUand a proper setup of the JVM if relevant. Finally, Boyer places an own implementationof a benchmark framework at the disposal.

Unfortunately, Sestoft’s conclusions are drawn from C# Mono17 and C# Microsoft in avirtualized Windows XP environment, both run on a MacOSX system. However, this

17Mono Project: http://www.mono-project.com/

8 CHAPTER 2. RELATED WORK

thesis is interested in examining the performance of the most modern virtual machines forJava and Microsoft C# on Windows. Also, in addition to numeric performance, insightinto benchmarks that go beyond number crunching, including the impact of asynchronyand network I/O treatment, is provided.The JVM comparison demoed by Bull et al. dates back to 1999 and was executed withvariants of the Sun JDK Version 1.2.1 as well as Microsoft SDK Version 3.2 on single-processor machines. In contrast, this thesis presents results that stem from measurementswith the latest JRE versions on multi-processor hardware. Also, their benchmarking suiteis designed for multi-purpose, Java-specific comparisons, whereas the implementation usedin this thesis is specialized to the domain of TomP2P. The same applies to Boyers solution,where the main focus is on algorithm comparison. Nevertheless, all three approaches havea similar API and internal logic that can be roughly divided into setup, execution andmeasurement, shutdown and result aggregation. Furthermore, this thesis analyzes .NET’svirtual machine, the Common Language Runtime (CLR), and thus adds inter-environmentcomparisons. In addition, instead of just measuring execution time, a look at the memoryconsumption as a further performance factor is taken. Even though heavily inspiredby Boyers hints, this thesis ignored some aspects by design due to the heterogeneity ofthe analyzed virtual machines. Thus, no attempts to detect JIT compilation or garbagecollection are undertaken since the respective behaviors during execution are of interest,too. However, the warm-up phases are respected and special treatment applied whenrelative performances are calculated.

Chapter 3

Proposed Solution

This chapter describes the approaches that are used to achieve a port of the TomP2P corefrom Java to .NET C# and how to achieve interoperability between the two. Furthermore,it discloses the way in which benchmark results are achieved and what needs to be respectedwhen inter-platform profiling is conducted.

3.1 Layout

Figure 3.1: The Java project structure. Figure 3.2: The .NET project structure.

The original TomP2P library consists of seven Java modules. The aim of this thesis isto produce an equivalent implementation in the .NET environment, so the starting pointis the port of TomP2P’s core. This core functionality resides in a dedicated project andincorporates about 95% of TomP2P’s extent (Status: April 2015). This section shows thecoherence for both the Java and .NET universe projects that are part of this work.Figure 3.1 depicts the straight-forward relations in the Java world. They indicate theexistence of a separate interoperability testing project (see Section 3.2.2) as well as astandalone benchmark project. Interrelations are kept simple by design in that both onlydepend on the core module. Note that all testing modules are part of their respectiveproject due to Apache Maven’s1 standard directory layout.

1Apache Maven: https://maven.apache.org/guides/introduction/introduction-to-the-

standard-directory-layout.html

9

10 CHAPTER 3. PROPOSED SOLUTION

Figure 3.2 shows a slightly more complex structure for the .NET side. Firstly, testingobtains a separate project according to a .NET convention, hence core tests reside in theTomP2P.Test.dll. Secondly, the interoperability module is declared a test project as all suchtesting is capsuled into unit tests (see Section 3.2.2). Thirdly, the TomP2P.Extensions.dllhas no counterpart in Java. It covers workarounds, ported data types not available in.NET, convenience and extension methods (see Section 3.3.3) as well as a stripped-downconversion of Netty’s buffers [30] (see Section 3.4). Table 3.1 discloses the mapping betweenall projects.

Java .NET

tomp2p-core TomP2P.Core, TomP2P.Tests

TomP2P.Extensionstomp2p-interop TomP2P.Tests.Interop

tomp2p-benchmark TomP2P.Benchmark

Table 3.1: Mapping between Java and .NET projects.

3.2 Interoperability

One of the goals of this thesis is to achieve interoperability between running Java and C#clients. This means that any TomP2P node, running on a JVM, can be substituted by anode running on a CLR and vice versa. Any node connecting to another node must beagnostic toward whether it effectively communicates with software written in one or theother language.

3.2.1 Interoperability Concerns

Because one of two sides already exists in this thesis’ scenario, the task of reachinginteroperability is special. So as to avoid refactoring and rewriting of the original Java code- provoking unavoidable conflicts with the ongoing development on the protocol layer -, theattempt is to leave the original code untouched. This means that the C# implementationmust adhere to the existing rules and formats.

Data Type Mapping

Data types are typically one of the main interoperability issues. If two systems need tocommunicate by exchanging data, a mutual syntactical understanding is required. Hence,an agreed mapping between the data types in Java and the data types in C# must exist.Regarding the primitive types used in Java, .NET’s Common Type System (CTS) definesa superset of so-called value types [22]. The unequal denomination is caused by .NET’sunified type system where value and reference types both are object-oriented and derive

3.2. INTEROPERABILITY 11

from a common root type. In contrast, for each primitive data type in Java, the core classlibrary provides a wrapper class that represents it as a reference type. Confusingly, suchwrapped types can be assigned null, whereas .NET value type objects are not allowed to.So as to induce this ability and correct the mapping, value types in .NET can be markedas nullable by using the ? -notation [25]. A look at Table 3.2 clarifies these relations.With respect to compound reference data types, including classes and other complex typesconstructed from primitive ones, the mapping depends on whether the type is defined bythe framework or by TomP2P. In case of a Java library class, the semantically most similartype is used in C#. However, if the reference type is specified by TomP2P, the whole classis ported into an equally named class. Section 3.3.2 reveals more concrete informationabout this sort of mapping.

Java .NET Range

Primitive Types Value Types

boolean bool true or false

byte sbyte -128 to 127

- byte 0 to 255

short short -32,768 to 32,767

- ushort 0 to 65535

char char unicode symbols

int int -2,147,483,648 to 2,147,483,647

- uint 0 to 4294967295

long long −263 to 263 − 1

- ulong 0 to 264

float float single-precision 32-bit IEEE 754 floating point

double double double-precision 64-bit IEEE 754 floating point

- decimal ±1.0 x 10e-28 to ±7.9 x 10e28

Reference Types

enum enum named constants

String string sequence of char

Character char?

same as above, including null

Boolean bool?

Byte sbyte?

Short short?

Integer int?

Long long?

Table 3.2: Mapping between Java and C# data types.

12 CHAPTER 3. PROPOSED SOLUTION

Messages

Jaimez-Gonzalez and Lucas [17] identify messages as another fundamental requirement forinter-operable systems. By means of standardized messages, communication between twoor more instances can happen. Luckily, and due to the typical architecture of distributedsystems, TomP2P already defines such a structure, the net.tomp2p.message.Message class,and uses it for its internal protocol. These messages contain several header fields that arenecessary to describe all possible types of network connections, sending options, requestand response types. In addition, payload fields enable the declaration of the encapsulatedcontent and allow the serialization instances to choose the correct encoding and decodingstrategy. Thus, besides consistent and correct serialization and de-serialization, it sufficesto port the Message Java class with all its associated logic.

Serialization and De-serialization

Serialization describes the process of rendering information into a state that can be savedpersistently or streamed through a network. De-serialization is the opposite process thatputs the serialized version back to its original state.TomP2P defines own encoder and decoder implementations for its messages. Thenet.tomp2p.message.Encoder transforms the state of live message objects into a binaryform by adhering to payload content specific rules. The net.tomp2p.message.Decoder doesthe exact same thing but inversely. Although basically simple and fast, special attentionis required when assembling an equivalent logic for the .NET world. By default, Javatreats its primitive bytes in a signed way, whereas .NET specifies two separate value typesfor signed and unsigned bytes. Furthermore, Java stores bytes in a Big Endian order,whereas .NET stores them in Little Endian fashion. Also, even though Java does notprovide unsigned integer types, TomP2P uses third-party libraries to obtain this capability.Table 3.3 illustrates this context. In order to cope with the endianness, the .NET side hasto perform a byte ordering process for each incoming and outgoing stream. Listing 3.1shows an exemplary conversion for an outgoing 4-byte integer, namely Little Endian toBig Endian.

Java .NET

Big Endian Little Endian

signed unsigned signed unsigned

byte

managed by Netty

sbyte byte

short short ushort

int int uint

long long ulong

Table 3.3: Differences between Java and .NET encoding/decoding.

3.2. INTEROPERABILITY 13

/// Writes a 4-byte integer to the current stream and

/// advances the stream position by 4 bytes.

public void WriteInt(int value)

{

// extract bytes from little -endian fashion (C#)

var b1 = (byte) (value >> 24);

var b2 = (byte) (value >> 16);

var b3 = (byte) (value >> 8);

var b4 = (byte) value;

// write bytes in big -endian fashion (Java)

_stream.Write(b1);

_stream.Write(b2);

_stream.Write(b3);

_stream.Write(b4);

}

Listing 3.1: C# conversion from Little Endian to Big Endian for a 4-byte integer.

With respect to inter-platform object transmission, TomP2P supports both Java object-serialization and binary raw data serialization. Since the former employs the built-in JDKserialization tools, no inter-operable solution for C# is possible. However, when it comes toobject-oriented languages, there exist some really sophisticated third-party solutions thatallow serialization and de-serialization between two environments. But leaving the originalcode untouched while nonetheless striving for interoperability discourages from externalservices, like Google’s Protocol Buffers [13]. Hence, object-serialization between Java and.NET environments is limited to raw byte transmission and has to follow predefined rulesin both implementations.

Algorithms

While semantically similar data structures can be found, they do not necessarily behave inthe same way. Often, this is due to different implementations of underlying algorithms. Mi-crosoft .NET’s System.Random is the one-to-one class equivalent of Java’s java.util.Random.Nonetheless, given the same seeding input, both classes generate unequal results. Thisconcerns the interoperability of TomP2P since the randomization algorithm is used assimple hash function for bloomfilters. The solution to this concrete example is to reverseengineer Java’s algorithm and provide it with a separate class for .NET. Sometimes, certainalgorithms are not present in one world and need to be adopted first (e.g., calculation ofthe broadcast IP). All of these are typical examples whose code realizations remain in theextensions project described in Section 3.1.

Cryptographic Interoperability

Achieving cryptographic interoperability is another concern related to serialization. TomP2Puses the DSA and RSA key generation algorithms in order to sign messages and protect dataaccess in the DHT. Unfortunately, porting Java public key hashes to C# is cumbersomebecause it either forces deviation from well established key formats of PKCS #8 and X.509

14 CHAPTER 3. PROPOSED SOLUTION

in order for C# to import or export keys using XML [35], or requires the usage of ASN.1.The latter approach is proposed by [34] and could include functionality of third-partylibraries that exist for both Java and C#, such as Bouncy Castle [3], that support readingand writing encoded ASN.1 objects. However, all approaches introduce changes to existingJava code and go beyond the scope of this thesis. Therefore, cryptographic interoperabilityis subject to future work (see Section 5.2).

3.2.2 Interoperability Testing

In order to cross-check the correctness of the interoperability, a separate test project isset up for both platforms (see Section 3.1). To simplify the testing process, the basicmechanism plans to execute the tests from within the .NET environment and havingthe Java side only react to requests. The two projects are designed with respect to thisperspective. Accordingly, all of the tests have the form of C# unit tests. Each test spawns aseparate sub-process executing the tomp2p.interop.jar which holds the verification code forthe Java side. By means of process input parameters, the respective verification sequencescan be triggered and executed. In order for the two running processes to exchange data,the local machine’s hard-drive is used as inter-process storage.

Protocol Tests

The most fundamental interoperability tests are those that ensure mutual understandingof primitive data types. They check for the correct serialization mapping, includingendianness conversion as described in Section 3.2.1. After having certainty about primitivetypes, the next abstraction layer to be tested is the protocol. TomP2P’s protocol isrepresented by the net.tomp2p.message.Message class (see Section 3.2.1). Here, testing forinteroperability involves the verification of correct encoding and decoding of such messagesbetween .NET and Java processes. All of these protocol interoperability tests are aboutconverting existing information into a binary format and verifying the correctness of thecontent after back conversion. It is important to note that encoding happens on oneplatform, whereas the respective decoding has to happen on the other, and vice versafor the other way round. In order to conduct a verification, the semantically exact samemessage object needs to be instantiated and used on both sides. Figure 3.3 demonstratesthe corresponding procedure, where C# encodes and Java decodes, by means of an UMLsequence diagram.

Remote Procedure Call Tests

Whereas protocol tests solely rely on raw binary data that is interchanged through bufferingon the local hard-disk, the Remote Procedure Call (RPC) interoperability tests describedin this segment also involve network traffic. The purpose of these tests is to verify thecorrectness of all of TomP2P’s RPC calls, such as pings, broadcasts, quit messages, and soon. The realization for this set of tests is slightly more complex. In contrast to the protocol

3.3. CODE EQUIVALENCE 15

Figure 3.3: Protocol interoperability test procedure, where a C# encoded message isdecoded by Java.

tests’ serial approach, where the JAR can be executed and the .NET process blocked untila result is returned, RPC tests require the Java process to return multiple asynchronousresults. Furthermore, a mechanism for providing multiple successive arguments, includingnetwork creation and shutdown instructions, as well as the actual test arguments, is needed.Therefore, after creating a Java-based P2P network, the .NET process asynchronouslyawaits the first result consisting of a peer address that it can use for the subsequent testing.Because there exists no other asynchrony-ready channel between the two platforms, theJava processes’ output stream is redirected and used for such inter-process communication.Of course, exchanging information this way requires attention handling of regular expressionpatterns. Now, although the Java process has returned a result, it must not exit, butrather keep the network running. Further successive arguments, such as the test argument,are equivalently passed through the redirected input stream. The UML sequence diagramin Figure 3.4 depicts the whole mechanism. Notice the notation for asynchronous calls forstandard in- and output communication.

3.3 Code Equivalence

When porting code, the most important requirement for the target language is the existenceof semantically equivalent constructs. Although Java and C# both are object-orientedlanguages that derive from common ancestors and share many programming concepts,

16 CHAPTER 3. PROPOSED SOLUTION

Figure 3.4: RPC interoperability test procedure, where C# requests and Java serves.

there are subtle differences. This section describes the methodologies used for the Java toC# code translation.

3.3.1 TomP2P Version

Since this thesis discusses the port of open-source software that is subject to ongoingdevelopment, a stable version has to be taken, such that progress on the original work doesnot interfere with the migration. After all, this report accomplishes inter-platform profilingtasks that require these platforms to run software that is as alike as possible. Thus, the Javaproject is branched on GitHub2 at commit ”55844fb1772ecfb28335d5865e2ee15cac4a9705”,12. October 2014. All subsequent work on the original is ignored and the migration ofnew features developed meanwhile has to be covered with future work (see Section 5.2).

2https://github.com/tomp2p/TomP2P

3.3. CODE EQUIVALENCE 17

3.3.2 Data Structures

It is important to establish a consistent mapping from Java to C# concepts in order toaccommodate current and future development efforts on the TomP2P project. WhereasSection 3.2.1 identified the fundamental differences and mapping concerning primitivedata types, this section concentrates on reference types. All reference types defined in thesource project need to be ported to the target language. Not uncommonly, however, theseare made up of built-in reference types defined by the Java Class Library (JCL). Amongothers, such classes include types such as collections, exceptions or locking mechanisms.In those scenarios, the semantically most equivalent .NET type needs to be found andused. Additionally, statically exposed helper methods that are typical for frameworkclasses defined in JCL or .NET mostly have a respective equivalent. Table 3.4 shows astripped-down version, showing examples of different aspects, of the mapping used in thiswork. The complete table can be found in Appendix A.1.

Aspect C# Java

Interfaces

Collection IEnumerable

List IList

Map IDictionary

Comparator<T> IComparer<T>

Collections

ArrayList<E> List<T>

BlockingQueue<E> BlockingCollection<T>

NavigableMapSortedDictionary

SortedMap

Exceptions

IllegalStateException InvalidOperationException

RuntimeException SystemException

NullPointerException NullReferenceException

MemoryBitSet BitArray

ByteBuffer MemoryStream

Networking

InetSocketAddress IPEndPoint

InetAddress IPAddress

SocketAddress EndPoint

Locking mechanisms

AtomicX Interlocked

CountDownLatch CountdownEvent

ReadWriteLock ReaderWriterLockSlim

TimingScheduledExecutorService Timer

TimeUnit TimeSpan

Static helper methodsCollections.unmodifiableX() ReadOnlyX or X.AsReadOnly()

System.identityHashcode() RuntimeHelpers.GetHashCode()

Table 3.4: Stripped-down table of the data structure mapping used in this thesis.

18 CHAPTER 3. PROPOSED SOLUTION

3.3.3 API Requirements

Ending up with C# code that resembles more or less the Java source includes the unitizedhandling of APIs. The requirements for this thesis include the following two statementsthat have been strictly obeyed:

� The .NET API must be designed in such a way that it will be similar to the JavaAPI. It needs to remain developer friendly and easy to understand.

� The .NET-specific conventions and programming methodologies shall be used.

Wrapping .NET Conventions

Unfortunately, these two requirements are intertwined because language conventions differand some concepts are applied differently. Concretely, it is often difficult to decide whetherto break the original Java API in favor of .NET methodologies. For this reason, there isalways a trade-off between these two. Mostly, however, it suffices to wrap .NET behaviorwith a Java-like API to comply with both. A good example for this is the atomic handlingof primitive value types. Whereas Java has separate reference types for this kind ofvariable modification, C# must use the System.Threading.Interlocked class [24] for atomicoperations. Hence, this work introduces a new type - leaning against Java’s type andexposing the same API - for each primitive type, accordingly. Listing 3.2 shows partialcode for the circumstance of Java’s AtomicInteger.

/// An approach to mimick Java’s AtomicInteger in .NET.

public class VolatileInteger

{

private int _value;

public VolatileInteger(int initialValue)

{

_value = initialValue;

}

public void Set(int newValue)

{

Interlocked.Exchange(ref _value , newValue);

}

public int Get()

{

var longVal = (long) _value;

return (int) Interlocked.Read(ref longVal);

}

// rest of the API hidden for the sake of brevity

}

Listing 3.2: Wrapped atomic operation handling for integers with a Java-like API.

3.3. CODE EQUIVALENCE 19

C# Extension Methods

Section 3.3.2 showed the necessity of finding an equivalent data structure or programmingconcept. Reusing an existing built-in type makes more sense than coming up with aseparate implementation. Understandably, these semantical equivalents do not necessarilyprovide the exact same set of features, much less the same API. For such scenarios -and with respect to the two requirements - the .NET version of TomP2P makes use ofextension methods [23]. Extension methods are a syntactical feature of the C# languagethat enable new methods to be added to existing types without the creation of derivedtypes, recompilation or otherwise modification of the original type. They are a specialkind of static method, but are called as if they were instance methods on the extendedtype. Thus, Java-like behavior can easily be added to existing .NET types by means ofsuch extension methods. This mechanism is used intensively for this thesis’ work, eitherto add non-existent behavior or to substitute existing methods with different pre- andpost-conditions (e.g., returning null instead of throwing an exception). Listing 3.3 showsan extension for the System.Collections.Generic.Queue<T> type where the post-conditionis changed to be on par with Java’s java.util.Queue<E> equivalent.

/// Equivalent to Java’s java.util.Queue <E>.peek().

/// Retrieves , but does not remove , the head of this queue , or returns

null if this queue is empty.

/// <typeparam name="T">Specifies the type of elements in the

queue.</typeparam >

/// <param name="q">The type to be extended.</param >

/// <returns >The head of this queue , or null if this queue is

empty.</returns >

public static T Peek2 <T>(this Queue <T> q) where T : class

{

try

{

return q.Count == 0 ? null : q.Peek();

}

catch (InvalidOperationException)

{

return null;

}

}

Listing 3.3: A sample C# extension method for .NET’s Queue<T> type.

3.3.4 Asynchrony

Many parts of the TomP2P library is about networking and I/O operations. Thus, hugeparts of its source code describes asynchronous behavior. In object-oriented environments,asynchrony is often implemented by means of future objects. Such a future is a stand-infor a computational result that is initially unknown, but becomes available at a later time.The process of calculating the result can occur in parallel with other computations. Insteadof explicitly waiting for the asynchronous work to complete using a blocking mechanism,the future is simply asked for its result when it is ready to be used. If the result is available,

20 CHAPTER 3. PROPOSED SOLUTION

it is returned immediately. If the asynchronous work has not yet finished, the thread thatneeds the result blocks until the result value becomes available.Java developers usually make use of the java.util.concurrent.Future<V> interface, butthis type has no notification mechanism that triggers as soon as the asynchronous result isavailable. For this reason, TomP2P comes with an own implementation of future objects,implementing the net.tomp2p.futures.BaseFuture interface, which can be listened to.In the Microsoft .NET Framework, the Task Parallel Library (TPL) includes a set oftypes and APIs that help the process of adding parallelism and concurrency. Futures areimplemented with the Task<TResult> class, where the type parameter TResult gives thetype of the result. In other words, a future in .NET is a task that returns a value.There are several differences between these particular future patterns. The most relevantones for this thesis’ port are stated here. Firstly, TomP2P’s approach is not generic andrequires a separate class for each result type. Secondly, the callbacks that are executedupon future completion differ in their execution manner. Whereas attached listeners toa BaseFuture object are executed serially, all so-called continuation tasks in .NET areactivated automatically to run in parallel when its antecedent task or tasks complete.Thirdly, the TPL comes with support for control flow, such as fork-join, or conditions,like when-all or when-any. In contrast, separate subtypes of BaseFuture have to beimplemented in Java. Last but not least, C# 5.0 offers the async and await keywordsthat allow developers to write asynchronous code almost as easily as synchronous code.From this syntactic sugar, the C# compiler generates a state-machine that handles thenecessary continuations without developers having to think about it. Listings 3.4 and 3.5show the same semantical implementation of an asynchronous channel creation. Clearly,C#’s implementation is much more concise. These and further differences between theasynchronous APIs are enlisted in Table 3.5. The complete mapping between the originalBaseFuture derivatives for Java and its C# counterparts can be found in Appendix A.2.

ChannelCreator cc = null;

FutureChannelCreator fcc =

recv1.connectionBean ().reservation ().create(1, 0);

fcc.awaitUninterruptibly ();

cc = fcc.channelCreator ();

Listing 3.4: Asynchronous channel creation in Java.

var cc = await recv1.ConnectionBean.Reservation.CreateAsync (1, 0);

Listing 3.5: Asynchronous channel creation in C# using the await keyword.

3.4 The Netty Project Counterparts

Peer-to-peer systems require network management mechanisms. Also, support for asyn-chronous network operations is fundamental. The tooling used for networking in both ofTomP2P’s implementations is discussed in this section. The Java version makes heavy useof a third-party library, called The Netty Project [29], which is a high performance JavaNIO client and server framework. Unfortunately, this library cannot be used for the .NET

3.4. THE NETTY PROJECT COUNTERPARTS 21

Aspect TomP2P Java TomP2P C#

Future objectsBaseFuture implementations Task, Task<TResult>

(e.g., FutureResponse) (e.g., Task<Message>)

Await awaitUninteruptibly() (blocking)await keyword (non-blocking)

Wait() (blocking)

Continuation BaseFutureListener (serial)ContinueWith() (parallel)

await keyword (serial)

Result orseparate accessor(s) returned by the await keyword

Exteption(s)

Flow and FutureForkJoin Task.WhenAll()

Conditions FutureLateJoin Task.WhenAny()

WrapperFutureWrapper

TaskCompletionSource<TResult>FutureWrapper2

Table 3.5: Asynchrony API differences between TomP2P for Java and C#.

side and suitable counterpart implementations for the various aspects of Netty’s abilitiesneed to be found. Because this third-party library is rather huge and complex, the mostessential properties used by TomP2P have been identified for this thesis, such that anappropriate attribution can be found for the port. The main properties are described inthe following subsections.

Channels & Sockets

All network communication of TomP2P is done over either TCP or UDP connections,depending on the context. Such TCP and UDP network programming is greatly simplifiedby Netty as it exposes APIs for various non-blocking connection operations, like socketlifetime management and network data transfer. All kinds of connections are referred toas channels in order to encapsulate and unify client and server socket logic.The solution found for the .NET port explicitly differentiates between client and serverside, but at least adopts the naming. Instead of relying to third-party code, all necessarychannel functionality is packed into four classes, as depicted in Figure 3.5, that internallyuse .NET built-in types that wrap the Windows Sockets API (WSA). Interfaces are used todefine the much needed subset of Netty’s exact same APIs. These built-in classes alreadyhave basic support for asynchronous data transfer. For this reason, the port makes use of.NET’s asynchrony concept (see Section 3.3.4) instead of adopting Netty’s own approach.All events needed on channels that are required to resemble Netty’s API are defined assubtypes of the ChannelEventHandler delegate.A powerful advantage of Netty connections is that they usually underlie a smart threadmanagement to ensure an optimal consume of resources. On the other hand, and dueto time saving measures, a best-effort solution is found for .NET to overcome typicalbottlenecks in areas like channel creation and server side service loops. Of course, theseapproaches can be assumed to scale worse than the sophisticated mechanisms of Netty.

22 CHAPTER 3. PROPOSED SOLUTION

Confirmation can be found in Section 4.3.3. Optimization, however, is not excluded, butsubject to future work (see Section 5.2).

Figure 3.5: The .NET-side architecture of channel elements.

ChannelPipeline & ChannelHandlers

The Netty project introduces the notion of a ChannelPipeline, which is a list of Chan-nelHandlers that handle or intercept inbound and outbound I/O events or operations ofa channel. Each channel has its own pipeline that is created automatically when a newchannel is instantiated. As described in the left-right flow in Figure 3.6, inbound eventsare handled by InboundHandlers and outbound events by OutboundHandlers, respectively.DuplexHandlers describe types that act as both incoming and outgoing event interceptors.This concept is heavily used in TomP2P’s core and hence needs an equivalent counterpartfor .NET.Like in the original Netty project, instances of the ChannelHandlerContext class enable

Figure 3.6: Typical I/O event processing by channel handlers in a pipeline.

handlers to interact with their pipeline and other handlers. The main benefit of suchcontext objects is that they encapsulate all state information associated with their channeland pipeline. Whereas channel-specific state can be derived from framework classes,pipeline-specific state need to be kept track of. Thus, all intermediate processing resultsfrom inbound and outbound handlers, potential exceptions or conditions, such as timeouts,undergo the responsibility of a per-channel, per-connection PipelineSession object. This

3.4. THE NETTY PROJECT COUNTERPARTS 23

class has no direct counterpart in the original Netty project, but rather merges somefunctionality of its ChannelHandlerContext and ChannelPipeline implementations. Likebefore, all necessary types are defined through interfaces that solely expose the mostcommonly used API. Figure 3.7 depicts the interactions and dependencies between all ofthese equivalents, under which IChannel, Pipeline and IChannelHandler represent themain actors. With this, all handlers defined in Java’s TomP2P can be cloned with thesame semantical functionality. The ISharable interface represents the equivalent to Java’s

Figure 3.7: The .NET-side architecture of channel pipeline and I/O event handlers.

@Sharable annotation and is used to mark channel handlers that are stateless. Suchhandlers can be instantiated once and added to multiple pipelines without respect to raceconditions. In contrast, unsharable handler objects contain state and need to be clonedfor each new PipelineSession.

Buffers

In order to transfer sequences of bytes, Netty uses its own buffer API that is backedby the JCLs java.nio.ByteBuffer type. Netty’s buffer type, io.netty.buffer.ByteBuf, hassignificant advantages in terms of extensibility and functionality. Furthermore, it providesa composite buffer that allows the creation of new buffers from arbitrary others with nomemory copy, while automatically extending its capacity. Such transparent zero copyingis important to lift up network application performance. Therefore, these buffer types arefrequently used in TomP2P’s core. To draw as near as possible to the same functionality in.NET, the most fundamental part of Netty’s buffer library, comprising only of the featuresactually needed in TomP2P, is ported to C#. Due to this port, the whole Netty buffer APIused in Java has its counterpart in .NET. However, since Netty’s buffer library containsmultiple Java-specific features that address performance improvements, some limits needto be set. Although bringing some disadvantages for the .NET memory allocation, Netty’sconcept of reference counting, which explicitly deallocates resources upon disuse, and theuse of direct buffers, which reside outside of the JVM heap and add zero copy capability,are not taken over. Again, possible solutions for similar behaviors need to be addressed infuture work (see Section 5.2).

24 CHAPTER 3. PROPOSED SOLUTION

3.5 Benchmark Suite

In order to execute benchmarks and compare the performance of TomP2P for Java and.NET, a separate suite is built. These benchmarks are not limited to code execution times,but also address the memory consumption of different virtual machines. This section isabout the methodology used in this thesis to gain the results presented in the subsequentchapter.

3.5.1 Benchmarking Approach

Robust benchmarking requires some basic understanding about what happens to managedcode when it is executed. Both Java and C# behave in a very similar manner in that theyboth are designed to be compiled to an intermediate language that can be interpretedby the respective virtual environment. In general, the initial execution time performanceof interpreted code is usually relatively slow, but then improves greatly for a while untilit reaches a steady-state. Assuming the steady-state performance needs to be measured,understanding about all the factors that lead up to it is needed. First of all, JVMs typicallyload classes only on their first usage. Hence, a code block’s first execution time includes theloading of all necessary classes, which usually involves disk I/O, parsing and verification.These side-effects add bias to the measurement results. Also, modern JVMs typically letcode run for a while in order to gather profiling information before doing Just-In-Time(JIT) compilation. During this time, code is purely interpreted. This means that a codeblock might need to execute many times before its steady-state profile emerges. TheCLR knows similar mechanisms and thus, this thesis’ benchmarking procedure includes awarm-up phase so as to prepare code on both platforms for their respective steady-state.The following scheme for benchmarking steady-state performance of particular code blocksis respected:

1. Execution of code block once to load all classes.

2. Execution of code block multiple times to arrive at its steady-state profile.

3. Execution of code block N more times.

4. Measurement of the execution time for each repetition ni.

5. Calculate the mean execution time as µ = 1N

∑Ni=1 ni.

6. Calculate the standard deviation from the mean as σ =√

1N

∑Ni=1(ni − µ)2.

Although these warm-up issues need to be respected for the statistical calculation, thedynamic behavior of the different virtual machines are interesting enough to be examined,as done with an over-time observation in Chapter 4.

3.5. BENCHMARK SUITE 25

3.5.2 Benchmark Procedure

Because this work investigates performances between different platforms, the use of separatethird-party profiling libraries for each platform would result in differently formatted output.Furthermore, the approach described in Section 3.5.1 could not be guaranteed. In fact,a new set of tools is built for Java and .NET that follow the exact same principles.As introduced in Section 3.1, the tomp2p-benchmark project contains the equivalentbenchmark suite code to .NET’s TomP2P.Benchmark assembly. Both represent consoleapplications that can be instructed via input parameters to execute the benchmarks ofdesire. Among others, these settings define the benchmark scenario to be executed, thenumber of execution times, including how many warmup rounds, the profiling mode, whichis either cpu or memory, and the directory where to write the results to. The wholeprocedure is operated by a set of scripts that apply the same parameters to the .NETexecutable and the Java Application Runnable (JAR). The basic batch script used forconfiguration and execution is shown in Appendix B. The Java benchmark runs on severaldifferent virtual machines. It is not only tested on the default client runtime, but also onthe server environment. Furthermore, all benchmarks are performed with Java versions7 and 8. Last but not least, the JAR runs on the IKVM presented in Section 2.4, suchthat an interpretation about a .NET-based Java virtual machine can be made. Once themeasurements are available for all VMs, the batch script automatically invokes an R scriptto generate the according plots. The whole benchmarking procedure is depicted in Figure3.8 by means of an UML sequence diagram.

Figure 3.8: The benchmark procedure for profiling different virtual machines.

26 CHAPTER 3. PROPOSED SOLUTION

Chapter 4

Benchmarking

This chapter presents the results obtained from benchmarking the Java and .NET versionsof TomP2P with respect to execution time and memory allocation. An interpretation isgiven for each scenario based on over-time observation for different virtual machines.

4.1 Setup Information

All benchmark measurements are executed on multiple virtual machines to observe differ-ences during the runtime. For this, the most recent releases of all virtual machines areused and run under Windows 8.1 x64, as specified in Table 4.1. With the exception ofthe Java servers, all programs are run on their respective virtual machine with defaultsettings (i.e., no JVM or CLR options are configured). The Java version of TomP2P hasbeen compiled to Java bytecode by means of Java’s 1.7.0 Update 79 compiler. In orderto compare benchmarking results from executions on different hardware and to includenetworking scenarios, the different host machines, enlisted in Table 4.2, are used. For eachof the conducted scenarios, different hosts hold different roles. Bandwidth information ofthe network used for both UDP and TCP remote connections is listed in Table 4.3.

Virtual Machine Version Settings

Java Client 7Oracle JVM 1.7.0 Update 79

default

Java Server 7 -server argument

Java Client 8Oracle JVM 1.8.0 Update 45

default

Java Server 8 -server argument

IKVM IKVM 7.2.4630.5 default

.NET Microsoft .NET CLR 4.5.2 default

Table 4.1: The virtual machines used for benchmarking.

27

28 CHAPTER 4. BENCHMARKING

Host Model CPU RAM OS

A Dell XPS 13 Intel Core i5-3337U @ 1.8 GHz 8.0 GB

Windows 8.1 x64B Lenovo T430 Intel Core i7-3520M @ 2.9 GHz 8.0 GB

C Lenovo T61 Intel Core 2 Duo T7500 @ 2.2 GHz 2.0 GB

Table 4.2: System information of the hosts used for benchmarking.

Protocol Minimum Maximum Average Info

UDP 113.07 MB/s 113.34 MB/s 113.07 MB/s 99.76% packet rate

TCP 111.44 MB/s 111.76 MB/s 111.76 MB/s

Table 4.3: Bandwidth information of the network used for benchmarking.

4.2 Execution Time

This section compares execution times for different scenarios, all including asynchronouscalls and network operations. Each scenario is benchmarked several times on all virtualmachines, such that representative mean values can be derived. A separate measurementis applied for the first few rounds, the warm-up phase, where the JVM gathers profilinginformation before doing optimized JIT compilation, as stated in Section 3.5.1. Afterthese warm-up rounds, the steady-state performance is assumed and particular mean andstandard deviation values are calculated.

4.2.1 Virtual Machine Comparison

To compare the execution time profile of all virtual machines listed in Table 4.1, a bootstrapscenario is defined. The benchmarked code blocks consist of several bootstrap operationsfrom client to server peers that all reside on the same local machine. Figure 4.1 showsthe results for this scenario, where host A served as the local machine. .NET’s CLRyields better results than all JVMs. The newer Java version 8 achieves slightly betterresults than its predecessor version. The respective client JVMs have a lower mean thantheir server counterparts. However, all JVMs follow a similar pattern concerning initialinterpretation and garbage collection, as indicated by the kicking peaks. Subsequentgarbage collection peaks even correlate to some degree between the different versions.Whereas these peaks seem to become larger over time, CLR iterations hardly spot outwhich makes the recognition of garbage collection attempts more difficult. The IKVM,although significantly slower than the rest, clearly shows its hybrid nature. As in .NET’sCLR, code blocks are JIT compiled at once and over-time execution times remain moreconsistent. However, the garbage collection peaks that appear in ever longer intervals, butwith increasing heights, reveal the behavior of a JVM.Because benchmarking on different hardware resulted in significantly different values, theexact same scenario is conducted on the more powerful host B. Figure 4.2 shows that

4.2. EXECUTION TIME 29

better results can be achieved with a newer and faster CPU. All results, including hostA and B, are specified in Table 4.4. The highlighted table cells show that .NET’s CLRyields the fastest results.

Figure 4.1: Execution time profile of the bootstrap scenario conducted on host A.

Figure 4.2: Execution time profile of the bootstrap scenario conducted on host B.

4.2.2 Warm-up Phase

The first 200 warm-up iterations, depicted in Figure 4.3, show that all JVMs requireseveral repetitions of the same code in order to arrive at a steady-state. During this time,Java bytecode is only interpreted instead of JIT compiled. In contrast, .NET needs onlysignificantly more time during its first execution and then remains in its steady-state. Thereason for this is the immediate JIT compilation for all intermediate language (MSIL)

30 CHAPTER 4. BENCHMARKING

blocks that are executed for the first time. Table 4.4 shows the execution times for thefirst and second repetition as well as the mean and standard deviation values for warm-upand steady-state phases, all in milliseconds.

Figure 4.3: Execution time profile of the bootstrap scenario warm-up phase.

VM First Second Warm-up Steady-State

Repetition Repetition 200 Repetitions 1000 Repetitions

Host A B A B A B A B

µ σ µ σ µ σ µ σ

J. C7 320.0 256.8 183.5 126.2 58.4 42.4 42.5 49.4 40.0 78.0 28.0 68.1

J. S7 283.0 185.8 193.1 113.2 56.2 42.8 33.2 26.7 41.2 85.4 21.3 43.6

J. C8 430.5 260.6 228.4 146.8 58.3 47.6 40.7 46.4 36.2 69.1 23.7 40.9

J. S8 371.0 251.4 224.6 130.3 54.6 40.0 32.7 33.9 37.0 74.6 19.4 35.8

IKVM 1496.5 987.7 134.1 79.3 141.2 102.6 86.9 66.5 136.6 61.3 89.0 41.5

.NET 220.9 161.7 21.6 60.1 23.6 14.6 19.1 11.5 22.7 3.92 18.5 4.4

Table 4.4: Execution time benchmark results of the bootstrap scenario, in milliseconds.

4.2.3 Local vs. Remote Networking

In order to compare the efficiency of network operations, according scenarios are bench-marked as well. For both protocols, UDP and TCP, the same data buffer of 1000 bytes istransferred both locally and remotely. Locally means that sending and receiving peersare hosted on the same machine and that data is only passed through the local networkinterface. Remotely means that sending and receiving peers are hosted on different ma-chines, where the bytes are transmitted through an external network infrastructure, whoseproperties are specified in Table 4.3. For all of these scenarios, host B runs the sending

4.3. MEMORY ALLOCATION 31

client peers while host C runs the receiving server peers. Comparing Figures 4.4 and 4.5shows that real networking I/O has a small impact on the execution times. Interestinglyenough, all benchmarked VMs achieve close results which might be due to the excess weightof I/O operations in contrast to the code block execution times. The same applies for TCPin Figures 4.6 and 4.7. As expected, TCP connections are slightly slower because multipledata packages are sent and each processed in the network stack and TomP2P pipelines.The warm-up phases of all four figures indicate faster execution times initially. Theserapidly slow down due to congestion on the socket layers because of multiple successivebenchmark repetitions. Table 4.5 contains all steady-state results and reveals that localconnections are faster for .NET, whereas remote connections yield better results in a JVM..NETs dominance on local machines might be due to Windows-internal optimizationsfor sockets, whereas the high-performance Netty Project library used in Java positivelyimpacts the results obtained from JVM benchmarks.The remote scenarios are also benchmarked in a network with an about 10 times worsebandwidth. The resulting values, however, do not differ significantly from those in Table4.5. Hence, the network latency is the bottleneck for these scenarios.

Figure 4.4: Execution time profile of the local UDP networking scenario.

4.3 Memory Allocation

The comparison of memory allocation on different virtual machines is done in this section.For different scenarios, the memory used by the respective processes are measured forseveral consecutive executions of the same code blocks. Again, all scenarios includeasynchronous calls and network operations.

4.3.1 Virtual Machine Comparison

In order to create a memory profile for all virtual machines, the same bootstrap scenariois used as in Section 4.2.1. Figure 4.8 represents the resulting profile for 1000 repetitions.

32 CHAPTER 4. BENCHMARKING

Figure 4.5: Execution time profile of the remote UDP networking scenario.

Figure 4.6: Execution time profile of the local TCP networking scenario.

Whereas all JVMs continuously and linearly allocate more and more memory over time,the CLR keeps the running process’ memory footprint steady. With default JVM settings,as used for all benchmarks in this thesis, Java takes as much memory as it gets until it iscapped at a limit (e.g., about 750 Mb in the figure 4.8). This limit, however, could bedecreased with the -Xmx<memory> JVM argument. The observable spikes identify thepoints in time where garbage collection is triggered. Again, Java 7 and 8 virtual machinesdeliver a highly similar profile concerning both allocation and deallocation. Accordingly,all their mean benchmarking results turn out within a tight interval. However, the JVM7 implementations seem to trigger garbage collection slightly earlier in comparison withthe respective JVM 8 counterpart. The IKVM again delivers results that lie between theothers. The memory allocation is not as aggressive as Java’s, but clearly does not remainas steady as .NET’s. However, its garbage collection spikes are relatively flat, suggestingthe implications of the underlying .NET memory deallocation strategy. For the measured

4.3. MEMORY ALLOCATION 33

Figure 4.7: Execution time profile of the remote TCP networking scenario.

VM Steady-State

1000 Repetitions

Protocol UDP TCP

Type Local Remote Local Remote

µ σ µ σ µ σ µ σ

Java C7 6.05 0.46 4.36 1.16 6.09 0.52 5.21 1.23

Java S7 6.01 0.48 4.39 1.12 6.21 0.55 5.16 1.20

Java C8 6.06 0.88 4.29 1.09 6.18 0.78 4.73 1.18

Java S8 6.04 0.83 4.29 1.43 6.15 1.17 4.73 2.27

IKVM 5.74 0.54 4.32 1.52 6.20 4.79 5.23 4.22

.NET 5.71 0.61 4.35 0.91 5.84 0.66 4.74 0.90

Table 4.5: Execution time benchmark results of the networking scenarios, in milliseconds.

1000 consecutive repetitions, all mean and standard deviation values are shown in Table4.6 with the best results highlighted.Since benchmarking the memory allocation on different hardware did yield similar valuesand thus, the creation of a profile on a different host is omitted.

4.3.2 Initial Phase

When it comes to memory allocation comparison, the initial phase is of special interestbecause the different virtual machines vary greatly in their allocation strategies. Asillustrated in Figure 4.9, all JVMs initially allocate about the same amount of memory.This memory rapidly increases over time as more repetitions of the benchmarked code isrun and thus more space is required. In contrast, the CLR allocates a much higher amountof memory, but keeps it steady during the whole lifetime of the process. Similarly, the

34 CHAPTER 4. BENCHMARKING

Figure 4.8: Memory allocation profile of the bootstrap scenario.

IKVM starts with a higher initial allocation, but linearly increases the amount of spacelike the other JVMs. Concerning the garbage collection, the CLR seems to deallocaterather often and immediately, whereas the JVMs wait ever longer with each collection call.Table 4.6 shows that Java wins with respect to initial allocation, but that .NET comeswith a much better prediction with respect to long-term execution.

Figure 4.9: Memory allocation profile of the bootstrap scenario initial phase.

4.3.3 UDP vs. TCP

To compare memory allocation regarding network operations with both UDP and TCP,the same scenario as in Section 4.2.3 is used, where 1000 bytes are transmitted. However,the memory footprints are only analyzed for the local scenario where sending and receiving

4.3. MEMORY ALLOCATION 35

VM First Initial Phase Consecutive

Allocation 100 Repetitions 1000 Repetitions

µ σ µ σ

Java C7 14.43 71.37 41.33 378.81 187.19

Java S7 14.78 64.24 39.89 374.26 194.91

Java C8 15.67 66.48 39.26 377.63 195.17

Java S8 15.36 68.82 39.43 382.88 194.61

IKVM 32.79 65.70 15.19 273.31 129.59

.NET 28.35 32.82 2.18 34.49 2.70

Table 4.6: Memory allocation benchmark results of the bootstrap scenario, in megabytes.

peers both run on host B. With this, the allocation amount for client and server parts areincluded in the results. Figures 4.10 and 4.11 show the UDP and TCP allocation profilesfor each 1000 repetitions. The initial allocations follow the same principles described inSection 4.3.2, but consecutive allocations follow different strategies. Although the JVMsnormally increase memory increasingly fast, these profiles show relatively flat slopes. Thisis due to Netty’s reference counting on buffers in order to achieve this exact behavior fornetworking applications. Note that the amount of memory used for direct buffers outsideof the JVM is included in the results. Another indication for Netty’s assist follows fromthe identical allocation results within the same Java versions. In contrast to executiontime, however, the older Java 7 wins in terms of memory footprint against its successor.On the other side, .NET’s profile looks different for UDP and TCP. In case of UDP, theresults get arbitrarily bad and even exceed the normally steady footprint, probably due toa memory leak in the current implementation. For TCP, on the other hand, a consistentstate is kept. Again, IKVM’s behavior is more close to CLR’s, but remains steady forboth protocols. Most probably, this is due to a mix of .NET-like garbage collection andNetty’s memory-specific optimization abilities. Table 4.7 contains all the results, includingthe first allocation in addition to mean and standard deviation values for all consecutiverepetitions.

VM UDP TCP

First Consecutive First Consecutive

Allocation 1000 Rep. Allocation 1000 Rep.

µ σ µ σ

Java C7 2.89 10.16 3.57 3.35 11.23 3.96

Java S7 2.89 10.16 3.57 3.35 11.24 3.97

Java C8 3.69 10.92 3.53 4.13 12.01 3.92

Java S8 3.69 10.91 3.52 4.13 12.01 3.93

IKVM 25.73 25.83 0.60 25.29 27.81 1.32

.NET 20.46 70.51 25.70 20.20 25.73 1.14

Table 4.7: Memory allocation benchmark results of the networking scenarios, in megabytes.

36 CHAPTER 4. BENCHMARKING

Figure 4.10: Memory allocation profile of the UDP networking scenario.

Figure 4.11: Memory allocation profile of the TCP networking scenario.

Chapter 5

Summary

This chapter comprises the conclusion of this thesis’ work and recapitulates the achievedgoals. Furthermore, it mentions possible directions for future work, including extensions andimprovements for TomP2P .NET, as well as furhter interesting benchmarking approaches.

5.1 Summary & Conclusion

This thesis presents the porting of the core functionality of the open-source TomP2P libraryfrom Java to .NET. Implemented with C#, the finished .NET version is inter-operablewith its Java counterpart. This interoperability is tested with particularly designed testcases and setups that go beyond the borders of single-platform testing. With respectto maintainability and future porting tasks, the new API resembles its Java archetypeand remains developer friendly and easy to understand. Moreover, the asynchronousprogramming model of .NET is used to simplify the handling of asynchrony. To copewith the functionality added by the third-party Netty library, semantically equivalentworkarounds are found for networking tasks. With the creation of a benchmark suitefor both platforms, performance profiles for various virtual machines are obtained andcompared. With respect to execution time, .NET yields better results, especially if certaincode blocks are run only a few times. In contrast, JVMs typically only interpret the firstseveral executions of the same code block in order to optimize subsequent compilation. Inthe long run, however, they both yield similar results. Benchmarking execution time forUDP and TCP network operations shows that latency is a bottleneck. Thus, the resultsfound for networking speed show an approximate tie. Relating to memory allocation, .NETinitially reserves more memory but typically keeps that footprint steady. This is unlikedefault JVM behavior, where less memory is allocated at first, but increased exceedinglyover time until it is capped at a limit. In case of UDP and TCP operations, TomP2P forJava outperforms the .NET version in terms of memory allocation, which is due to Netty’soptimization mechanisms for network buffers. This includes the usage of memory allocatedwith direct buffers that reside outside of the JVM heap and add zero-copy capability tothe application. In addition to the comparison of runtime behavior, benchmarking turnsout to be useful for the detection of implementation flaws, such as the memory leak in

37

38 CHAPTER 5. SUMMARY

UDP scenarios for TomP2P .NET. Overall, TomP2P for .NET is a compatible port of itsJava predecessor.

5.2 Future Work

To keep up with the development of the TomP2P .NET library, many tasks can benamed. First of all, and to complete the overall functionality of TomP2P’s core package,cryptographic interoperability needs to be added, including message signing and contentprotection. The third-party Bouncy Castle [3] library could be of aid for this undertaking.Furthermore, the support of object serialization as an addition to pure binary serializationcould be considered. This might be achieved with further third-party software, suchas Google’s Protocol Buffers [13]. Also, because development on the Java version hascontinued since it has been forked for this thesis’ goals, the backlog including all newcommits needs to be cleared. This work describes the port of the core package, whichaccounts for 95% of TomP2P, but future work could include the porting of the rest of theoriginal parts to complete the .NET version. To improve its performance, optimizationmechanisms, such as Netty’s reference counting or the use of direct buffers for reducedmemory usage within the virtual machine, could be introduced. This may either includefurther porting or finding a .NET-specific equivalent. The future release of .NET Core 5[28] opens the door for inter-platform benchmarking. Once, C# code can also be executedon Linux and Mac, creating execution time and memory allocation profiles for differentoperating systems would be the next logical step.

Bibliography

[1] Bitsquare. (2015). Bitsquare - The decentralized bitcoin exchange. Retrieved April 24,2015, from https://bitsquare.io/

[2] Bocek, T. (2015). TomP2P - A P2P-based High Performance Key-Value Pair StorageLibrary. Retrieved April 24, 2015, from http://www.tomp2p.net/

[3] Bouncy Castle. (2015). The Legion of the Bouncy Castle. Retrieved April 24, 2015,from https://www.bouncycastle.org/

[4] Boyer, B. (2008, June 24). Robust Java Benchmarking. IBM Developer Works.,Retrieved April 24, 2015, from http://www.ibm.com/developerworks/library/j-

benchmark1/

[5] Bull, J. M., Smith, L. A., Westhead, M. D., Henty, D. S., & Davey, R. A. (1999).A Benchmark Suite for High Performance Java. In Proceedings of ACM 1999 JavaGrande Conference, 81-88.

[6] Chandra, S. S., & Chandra, K. (2005) A Comparison of Java and C#.J. Comput. Sci.Coll., 20(3), 238-254.

[7] Chappell, D. (2002). Understanding .NET - A Tutorial and Analysis. Boston: Addison-Wesley Professional.

[8] Cisco. (2015). Cisco Visual Networking Index - Global Mobile Data Traf-fic Forecast Update 2014-2019. Retrieved April 24, 2015, from http:

//www.cisco.com/c/en/us/solutions/collateral/service-provider/visual-

networking-index-vni/white_paper_c11-520862.html

[9] Citrin, W. (2009, October 22). Java/.NET Interoperability: Web Services Aren’t Al-ways the Answer. DevX - The Know-How behind Application Development., RetrievedApril 24, 2015, from http://www.devx.com/enterprise/Article/43086

[10] Eaddy, M. (2001, February 1). C# Versus Java. Dr. Dobbs . The World of SoftwareDevelopment., Retrieved April 24, 2015, from http://www.drdobbs.com/windows/c-

versus-java/184404487

[11] El-Ramly, M., Eltayeb, R., & Alla, H. A. (2006). An Experiment in AutomaticConversion of Legacy Java Programs to C#. IEEE International Conference onComputer Systems and Applications, 1037-1045. doi:10.1109/AICCSA.2006.205215

39

40 BIBLIOGRAPHY

[12] Friedman, N. (2013). Eight Reasons C# is the Best Language for Mobile Develop-ment. Retrieved April 24, 2015, from http://blog.xamarin.com/eight-reasons-

c-sharp-is-the-best-language-for-mobile-development/

[13] Google. (2014, September 3). Protocol Buffers. Google Developers., Retrieved April24, 2015, from https://developers.google.com/protocol-buffers/

[14] Hecht, F. V., Bocek, T., Morariu, C., Hausheer, D., & Stiller, B. (2008) LiveShift:Peer-to-Peer Live Streaming with Distributed Time-Shifting. in 8th InternationalConference on Peer-to-Peer Computing, Aachen, Germany.

[15] Hive2Hive. (2015). Hive2Hive - Open-Source Library for P2P-based File Synchroniza-tion and Sharing. Retrieved April 24, 2015, from http://hive2hive.com/

[16] Intel. (2012, March 7). Java-.NET Interoperate via JNBridgePro andIntel-based Platforms. Developer Zone., Retrieved April 24, 2015, fromhttps://software.intel.com/en-us/articles/java-net-interoperate-via-

jnbridgepro-and-intel-based-platforms

[17] Jaimez-GonzA¡lez, C. R., & Lucas, S. M. (2011). Interoperability of Java and C#with Web Objects in XML. In Proceedings of the IADIS International Converence one-Society. International Association for the Development of the Information Society(IADIS), 518-522.

[18] JNBridge. (2015). JNBridgePro - How It Works. Retrieved April 24, 2015, fromhttp://jnbridge.com/software/jnbridgepro/how-it-works

[19] JNBridge. (2015). JNBridge - Spanning Java & .NET. Retrieved April 24, 2015, fromhttp://jnbridge.com/software/jnbridgepro/overview

[20] Landwerth, I. (2014, November 12). .NET Core is Open Source. .NETBlog - A First Hand Look from the Engineering Teams., Retrieved April 24,2015, from http://blogs.msdn.com/b/dotnet/archive/2014/11/12/net-core-

is-open-source.aspx

[21] Massi, B. (2015, February 15). Understanding .NET 2015. Microsoft Server &Tools Blogs., Retrieved April 24, 2015, from http://blogs.msdn.com/b/bethmassi/

archive/2015/02/25/understanding-net-2015.aspx

[22] Microsoft. (n.d.). Common Type System. MSDN - Microsoft Developer Network.,Retrieved April 24, 2015, from https://msdn.microsoft.com/en-us/library/

vstudio/zcx1eb1e(v=vs.100).aspx

[23] Microsoft. (n.d.). Extension Methods (C# Programming Guide). MSDN - MicrosoftDeveloper Network., Retrieved April 24, 2015, from https://msdn.microsoft.com/

en-us//library/bb383977.aspx

[24] Microsoft. (n.d.). Interlocked Class. MSDN - Microsoft Developer Network., Re-trieved April 24, 2015, from https://msdn.microsoft.com/en-us/library/system.

threading.interlocked\%28v=vs.110\%29.aspx

BIBLIOGRAPHY 41

[25] Microsoft. (n.d.). Nullable<T> Structure. MSDN - Microsoft Developer Network.,Retrieved April 24, 2015, from https://msdn.microsoft.com/en-us/library/

b3h38hb0\%28v=vs.110\%29.aspx

[26] Microsoft. (n.d.). Visual J#. MSDN - Microsoft Developer Network., Retrieved Aprile24, 2015, from https://msdn.microsoft.com/de-de/vstudio/bb188593

[27] Neffenger, J. (1998, August 1). Which Java VM Scales Best?. Java World., Re-trieved April 24, 2015, from http://www.javaworld.com/article/2076748/java-

web-development/which-java-vm-scales-best-.html

[28] .NET Foundation. (2014) .NET Core 5. Retrieved April 24, 2015, from https:

//www.dotnetfoundation.org/netcore5

[29] The Netty Project. (2015). Asynchronous Event-Driven Network Application Frame-work for Rapid Development of Maintainable High Performance Protocol Servers &Clients. Retrieved April 24, 2015, from http://netty.io/index.html

[30] The Netty Project. (2015). Package io.netty.buffer. Retrieved April 24, 2015, fromhttps://netty.io/4.0/api/io/netty/buffer/package-summary.html

[31] Obasanjo, D. (2007). A Comparison of Microsoft’s C# Programming Language ToSun Microsystems’ Java Programming Language. Retrieved April 24, 2015, fromhttp://www.25hoursaday.com/csharpvsjava.html

[32] PeerWasp. (2015). PeerWasp - A New and Secure P2P File Synchronization andSharing Solution. Retrieved April 24, 2015, from http://www.peerwasp.com/

[33] Sestoft, P. (2010). Numeric Performance in C, C# and Java. IT University ofCopenhagen, Denmark.

[34] Shaheryar, C. (2004, October 26). Porting Java Public Key Hash to C#.NET. CodeProject., Retrieved April 24, 2015, from http://www.codeproject.com/Articles/

6623/Porting-Java-Public-Key-Hash-to-C-NET

[35] Walton, J. (2008, June 5). Cryptographic Interoperability: Keys. Code Project.,Retrieved April 24, 2015, fromhttp://www.codeproject.com/Articles/25487/

Cryptographic-Interoperability-Keys

42 BIBLIOGRAPHY

Abbreviations

API Application Program InterfaceASN.1 Abstract Syntax Notation OneCLR Common Language RuntimeCPU Central Processing UnitDHT Distributed Hash TableDSA Digital Signature AlgorithmIDE Integrated Development EnvironmentI/O Input/OutputJAR Java Application RunnableJCL Java Class LibraryJDK Java Development KitJIT Just-In-TimeJRE Java Runtime EnvironmentJVM Java Virtual MachineMSIL Microsoft Intermediate LanguageNIO Non-blocking I/OOS Operating SystemP2P Peer-to-PeerRAM Random Access MemoryRFC Request for CommentsRPC Remote Procedure CallTCP Transmission Control ProtocolTPL Task Parallel LibraryUDP User Datagram ProtocolUML Unified Modeling LanguageVM Virtual MachineWFC Windows Foundation ClassesXML Extensible Markup Language

43

44 ABBREVIATONS

List of Figures

3.1 The Java project structure. . . . . . . . . . . . . . . . . . . . . . . . . . . 9

3.2 The .NET project structure. . . . . . . . . . . . . . . . . . . . . . . . . . . 9

3.3 Protocol interoperability test procedure, where a C# encoded message isdecoded by Java. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

3.4 RPC interoperability test procedure, where C# requests and Java serves. . 16

3.5 The .NET-side architecture of channel elements. . . . . . . . . . . . . . . . 22

3.6 Typical I/O event processing by channel handlers in a pipeline. . . . . . . 22

3.7 The .NET-side architecture of channel pipeline and I/O event handlers. . . 23

3.8 The benchmark procedure for profiling different virtual machines. . . . . . 25

4.1 Execution time profile of the bootstrap scenario conducted on host A. . . . 29

4.2 Execution time profile of the bootstrap scenario conducted on host B. . . . 29

4.3 Execution time profile of the bootstrap scenario warm-up phase. . . . . . . 30

4.4 Execution time profile of the local UDP networking scenario. . . . . . . . . 31

4.5 Execution time profile of the remote UDP networking scenario. . . . . . . . 32

4.6 Execution time profile of the local TCP networking scenario. . . . . . . . . 32

4.7 Execution time profile of the remote TCP networking scenario. . . . . . . . 33

4.8 Memory allocation profile of the bootstrap scenario. . . . . . . . . . . . . . 34

4.9 Memory allocation profile of the bootstrap scenario initial phase. . . . . . . 34

4.10 Memory allocation profile of the UDP networking scenario. . . . . . . . . . 36

4.11 Memory allocation profile of the TCP networking scenario. . . . . . . . . . 36

45

46 LIST OF FIGURES

List of Tables

3.1 Mapping between Java and .NET projects. . . . . . . . . . . . . . . . . . . 10

3.2 Mapping between Java and C# data types. . . . . . . . . . . . . . . . . . . 11

3.3 Differences between Java and .NET encoding/decoding. . . . . . . . . . . . 12

3.4 Stripped-down table of the data structure mapping used in this thesis. . . . 17

3.5 Asynchrony API differences between TomP2P for Java and C#. . . . . . . 21

4.1 The virtual machines used for benchmarking. . . . . . . . . . . . . . . . . . 27

4.2 System information of the hosts used for benchmarking. . . . . . . . . . . . 28

4.3 Bandwidth information of the network used for benchmarking. . . . . . . . 28

4.4 Execution time benchmark results of the bootstrap scenario, in milliseconds. 30

4.5 Execution time benchmark results of the networking scenarios, in milliseconds. 33

4.6 Memory allocation benchmark results of the bootstrap scenario, in megabytes. 35

4.7 Memory allocation benchmark results of the networking scenarios, inmegabytes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

A.1 Mapping from Java to C# used for TomP2P. (Part 1) . . . . . . . . . . . . 52

A.2 Mapping from Java to C# used for TomP2P. (Part 2) . . . . . . . . . . . . 53

A.3 Mapping between asynchrony handles for TomP2P in Java and C#. . . . . 54

47

48 LIST OF TABLES

List of Listings

3.1 C# conversion from Little Endian to Big Endian for a 4-byte integer. . 133.2 Wrapped atomic operation handling for integers with a Java-like API. . 183.3 A sample C# extension method for .NET’s Queue<T> type. . . . . . . 193.4 Asynchronous channel creation in Java. . . . . . . . . . . . . . . . . . . 203.5 Asynchronous channel creation in C# using the await keyword. . . . . . 20B.1 The benchmark-base.bat command line script for configuring and running

benchmark scenarios. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

49

50 LIST OF LISTINGS

Appendix A

Mapping from Java to C#

This appendix consists of the whole Java to C# mapping used for the porting donein this thesis. This includes platform-specific keywords and built-in types as well asTomP2P-specific differences for asynchronous result handles.

A.1 Keywords & Framework Types

Tables A.1 and A.2 specify the mapping for keywords and built-in framework referencetypes as used for this thesis.

A.2 Java Futures to C# Tasks

Table A.3 specifies the mapping between implementations of TomP2P’s BaseFuture inter-face in Java and the according .NET counterparts as used for this thesis.

51

52 APPENDIX A. MAPPING FROM JAVA TO C#

Java C#

Keywords

static final const

final

class-level: sealed

property-level: readonly

statement-level: const

parameter-level: no equivalent

instanceof is

undef. nr. of params with ... params

synchronized

method-level:

[MethodImpl(MethodImplOptions.Synchronized)]

statement-level: lock

Interfaces

Collection IEnumerable

Map IDictionary

List IList

Comaparable<T> IComparable<T>

Comparator<T> IComparer<T>

Inet4Address AddressFamily.InternetNetwork enum

Inet6Address AddressFamily.InternetNetworkV6 enum

Exceptions

Throwable Exception

Exception.printStackTrace() Console.WriteLine(Exception.ToString())

IllegalArgumentException ArgumentException

IllegalStateExecption InvalidOperationException

IndexOutOfBoundException IndexOutOfRangeException

NullPointerException NullReferenceException

RuntimeException SystemException

UnsupportedOperationException NotSupportedException

Collection Implementations

ArrayList<E> List<T>

BlockingQueue<E> BlockingCollection<T>

ConcurrentHashMap ConcurrentDictionary

LinkedHashMap TomP2P.Extension.Workaround.LruCache

NaviagableMap SortedDictionary

NaviagableSet SortedSet

Set HashSet or SortedSet

SortedMap SortedDictionary

Table A.1: Mapping from Java to C# used for TomP2P. (Part 1)

A.2. JAVA FUTURES TO C# TASKS 53

Java C#

Collection Utils

Iterator IEnumerable.GetEnumerator()

Collections.unmodifiableX() ReadOnlyX or X.AsReadOnly()

Collections.synchronizedList() SynchronizedCollection or BlockingCollection

List.equals() (respecting order) IEnumerable.SequenceEquals()

Timing

ScheduledExecutorService System.Timers.Timer or System.Threading.Timer

TimeUnit TimeSpan

Locking

AtomicReferenceFieldUpdater Interlocked.CompareExchange()

AtomicX Interlocked

AtomicInteger TomP2P.Extensions.Workaround.VolatileInteger

AtomicLong or volatile long TomP2P.Extensions.Workaround.VolatileLong

ReadWriteLock ReaderWriterLockSlim

CountDownLatch CountdownEvent

Semaphore (incrementing) Semaphore (decrementing)

Networking

InetSocketAddress IPEndPoint

InetAddress IPAddress

SocketAddress EndPoint

Memory

BitSet BitArray

ByteBuffer and Buffer MemoryStream

Utils & Others

System.identityHashcode RuntimeHelpers.GetHashCode()

System.currentTimeMillis() TomP2P.Extensions.Convenient.CurrentTimeMillis()

Enum.ordinal() (int) EnumType

Random TomP2P.Extensions.InteropRandom

Table A.2: Mapping from Java to C# used for TomP2P. (Part 2)

54 APPENDIX A. MAPPING FROM JAVA TO C#

TomP2P Java TomP2P C#

FutureBootstrapTcsWrappedBootstrap<Task>

FutureWrappedBootstrap

FutureChannelCreatorAPI: Task<ChannelCreator>

Inside: TaskCompletionSource<ChannelCreator>

FutureDirect TomP2P.Core.Future.TcsDirect

FutureDiscover TomP2P.Core.Future.TcsDiscover

FutureDoneAPI: Task

Inside: TaskCompletionSource<object>

FutureDone<K>API: Task<T>

Inside: TaskCompletionSource<T>

FutureForkJoin TomP2P.Core.Future.TcsForkJoin

FutureLateJoin TomP2P.Core.Future.TcsLateJoin

FuturePeerConnection TomP2P.Core.Future.TcsPeerConnection

FuturePingAPI: Task<PeerAddress>

Inside: TaskCompletionSource<PeerAddress>

FutureResponseAPI: Task<Message>

Inside: TaskCompletionSource<Message>

FutureRouting TomP2P.Core.Future.TcsRouting

FutureWrapper TomP2P.Core.Future.TcsWrapper

Table A.3: Mapping between asynchrony handles for TomP2P in Java and C#.

Appendix B

Benchmarking Script

Listing B.1 shows the Windows Batch script used for configuring and running benchmarkscenarios on different virtual machines. All further benchmark scripts, including R scriptsfor statistical calculation and image creation, can be found on the attached CD-ROM (seeAppendix E).

@ECHO OFF

:: [bmArg] [type] [nrWarmups] [nrRepetitions] [resultsDir]

SET bmArg="bootstrap"

SET type="memory"

SET nrWarmups =200

SET nrRepetitions =1000

SET resultsDir="%~dp0results"

SET suffix=""

:: Get newest binaries

ECHO Copy newest binaries ...

SET source=

"C:\Users\Christian\Source\Repos\TomP2P-.NET\TomP2P\TomP2P.Benchmark\bin\Release"

SET target="C:\Users\Christian\Desktop\benchmarking\NET"

xcopy.exe /s /y %source% %target%

:: Force pending idle tasks to be executed immediately

ECHO WINDOWS: Forcing pending idle tasks to be executed ...

Rundll32.exe advapi32.dll ,ProcessIdleTasks

ECHO TomP2P Benchmarking

ECHO Results will be stored in %resultsDir%.

:: Execute benchmarks

ECHO Executing .NET benchmarks ...

NET\TomP2P.Benchmark.exe %bmArg% %type% %nrWarmups% %nrRepetitions% %resultsDir%

%suffix%

ECHO Executing Java Client (JRE 7) benchmarks ...

SET jre="C:\Program Files\Java\jre7\bin\java"

SET suffix="C7"

%jre% -cp "Java\TomP2P.Benchmark.jar:logback.xml" -jar "Java\TomP2P.Benchmark.jar"

%bmArg% %type% %nrWarmups% %nrRepetitions% %resultsDir% %suffix%

ECHO Executing Java Server (JRE 7) benchmarks ...

SET suffix="S7"

%jre% -server -cp "Java\TomP2P.Benchmark.jar:logback.xml" -jar

"Java\TomP2P.Benchmark.jar" %bmArg% %type% %nrWarmups% %nrRepetitions%

%resultsDir% %suffix%

ECHO Executing Java Client (JRE 8) benchmarks ...

SET jre="C:\Program Files\Java\jre1 .8.0 _45\bin\java"

55

56 APPENDIX B. BENCHMARKING SCRIPT

SET suffix="C8"

%jre% -cp "Java\TomP2P.Benchmark.jar:logback.xml" -jar "Java\TomP2P.Benchmark.jar"

%bmArg% %type% %nrWarmups% %nrRepetitions% %resultsDir% %suffix%

ECHO Executing Java Server (JRE 8) benchmarks ...

SET suffix="S8"

%jre% -server -cp "Java\TomP2P.Benchmark.jar:logback.xml" -jar

"Java\TomP2P.Benchmark.jar" %bmArg% %type% %nrWarmups% %nrRepetitions%

%resultsDir% %suffix%

ECHO Executing IKVM benchmarks ...

SET ikvm="ikvm-7 .2.4630.5\ bin\ikvm"

SET suffix="IKVM"

%ikvm% -cp "Java\TomP2P.Benchmark.jar:logback.xml" -jar "Java\TomP2P.Benchmark.jar"

%bmArg% %type% %nrWarmups% %nrRepetitions% %resultsDir% %suffix%

:: Run R script

ECHO Running R script ...

CALL plot.bat %bmArg% %type% %nrWarmups% %nrRepetitions%

PAUSE

Listing B.1: The benchmark-base.bat command line script for configuring and runningbenchmark scenarios.

Appendix C

Tools, Frameworks & Languages

TomP2P 4Advanced open-source Java DHT library. Used as precursor for the port to TomP2P .NET.

Microsoft Visual Studio 2013 UltimateMicrosoft’s multi-language development environment (IDE). Used in this thesis for thedevelopment and management of TomP2P .NET C# source code.

Eclipse LunaJava development environment (IDE). Used for the development and management ofTomP2P’s Java source code.

Microsoft .NET Framework 4.5.2 and C# 5.0Microsoft’s software framework and runtime environment. C# is a multi-paradigm,general-purpose and object-oriented programming language. Both are used for the imple-mentation of TomP2P .NET and additional projects required for interoperability testingand benchmarking.

Oracle JDK 1.7, 1.8 and Java 7Oracle’s Java development kit and runtime environment. Java is a general-purpose andobject-oriented programming language. Both are used for the implementation of additionalTomP2P projects required for interoperability testing and benchmarking.

IKVM.NET 7.2An implementation of Java for the Microsoft .NET Framework, including a JVM and JCLimplemented in .NET. Used for benchmark comparison with original JVMs and the CLR.

57

58 APPENDIX C. TOOLS, FRAMEWORKS & LANGUAGES

Git 2.3.6Open-source distributed version control system. Used for the version management of bothJava and C# source code.

GitHubWeb-based Git repository hosting service, offering distributed revision control and sourcecode management functionality. Used as remote Git repository for both Java and C#source code.

Apache Maven 3.3.1Software project management and comprehension tool. Used for the management of Javaprojects and its dependencies in Eclipse.

NuGet 2.8.5Package manager for the Microsoft development platform. Used as central packagerepository of .NET projects in Visual Studio.

PsPing 2.01Windows system internal command-line tool for the administration of local and remotesystems. Used for the measurement of network bandwidth in benchmarking scenarios.

TeXstudio 2.9.4Open-source integrated environment for Windows for the creation of LaTeX documents.Used for the composition of this thesis document.

R Project 3.2.0Free language and software environment for statistical computing and graphics. Used forthe calculation and graphical representation of benchmarking statistics.

Paint.NET 4.0.5Open-source image and photo editing software for Windows. Used for the generation andmanipulation of images in this thesis.

Microsoft Visio 2013Flow-chart and diagram layout software. Used for the creation of sequence diagrams.

Appendix D

Installation Guidelines

D.1 TomP2P .NET

The following describes the setup of the TomP2P.NET solution for Visual Studio 2013.

1. Using Git, clone the TomP2P .NET repository from GitHub with https://github.

com/tomp2p/TomP2P-.NET.git.

2. Start Visual Studio and open the Team Explorer window.

3. Click the Open... button and navigate to the local Git repository.

4. Select the TomP2P.sln solution file in order to import it.

5. Install the following packages from NuGet (https://www.nuget.org/):

NLog Advanced .NET logging.

NUnit Unit-testing framework for all .NET languages.

D.2 Interoperability Testing

In order to execute interoperability tests, the following steps can be used.

1. Open the TomP2P .NET solution in Visual Studio. (see Appendix D.1)

2. Navigate to the TomP2P.Tests.Interop project.

3. Open the JarRunner.cs class and configure the following variables:

TmpDir Global path to the working directory of interoperability tests.(e.g., ”C:/Users/UserName/Desktop/interop/”)

59

60 APPENDIX D. INSTALLATION GUIDELINES

JavaExecutable The global path to the java command.(e.g., ”C:/Program Files/Java/jre7/bin/java.exe”)

JavaArgs The arguments provided to the java command.Use ”-jar [TmpDir]/TomP2P.Interop.jar”, where [TmpDir] must be replacedwith the according value set above.

4. Copy the /Software/Interoperability/TomP2P.Interop.jar file from the CD to thespecified TmpDir folder.

5. In the TomP2P.Tests.Interop project, right-click on the test class of choice andexecute the Run Unit Tests command.

6. The running interoperability tests collaborate with the TomP2P.Interop.jar. Allgenerated input and output results used for testing are written to the specifiedTmpDir folder.

D.3 Benchmark Suite

The following describes the correct use of the benchmarking suite on Windows. Necessarytools, executables and scripts are part of the suite and part of the attached CD-ROM. Allmentioned file paths can be changed in the respective source files.

1. Copy the /Software/Benchmarking/Benchmarking Suite/ folder from the CD-ROM(see Appendix E) to the desktop.

2. The suite contains the benchmark-base.bat file, shown in Appendix B. The followingparameters can be configured:

bmArg The benchmark scenario (e.g., ”bootstrap” or ”send-remote-udp”)

type The benchmark type: ”cpu” or ”memory”.

nrWarmups The number of warm-up iterations. (e.g., 200 )

nrRepetitions The number of repetition iterations. (e.g., 1000 )

resultsDir The path to the directory where results shall be stored. (Default”% dp0results” is recommended.)

3. Run the batch file. All virtual machines are benchmarked and the results written tothe hard disk.

4. All results, including the generated statistical graphics, can be extracted from thespecified results folder. (Default: /results)

Appendix E

Contents of the CD-ROM

/

Abstract.txt................................................English abstractZusfsg.txt..................................................German abstractMidterm Presentation...............................PowerPoint PresentationRelated Work Papers .........................................Papers in PDFSoftware

Benchmarking

Benchmarking Suite ............................Executables and scriptsBenchmarks ..............................................MeasurementsScenario Results....................................Evaluated Results

Interoperability

Test Results..........................................Binary test dataTomP2P.Interop.jar....................................Java executable

TomP2P .NET Source Code .................Complete Visual Studio solutionTomP2P Java Source Code ........................Complete Eclipse project

Thesis Source Files ......................................LaTeX source filesPorting TomP2P to .NET - Benchmarking P2P in Java and C#.pdf...Report

61