Warning: include(/home/luiscorb/public_html/include/firstlayout.php) [function.include]: failed to open stream: No such file or directory in C:\Inetpub\wwwroot\corbete\ArchivosTrabajos\proyecto.php on line 14

Warning: include() [function.include]: Failed opening '/home/luiscorb/public_html/include/firstlayout.php' for inclusion (include_path='.;C:\php5\pear') in C:\Inetpub\wwwroot\corbete\ArchivosTrabajos\proyecto.php on line 14
 

A continuación se desarrolla mi proyecto final de carrera. Está divido en dos partes. La primera parte demuestra los test y programas realizados para identificar las diferencias de programación entre Java y C++. Estos archivos pueden ser descargados para ver su funcionamiento. La segunda parte se explica teóricamente las diferencias entre los dos lenguajes. La diferencias en programación, implementación, velocidad de ejecución etc.
El proyecto esta escrito en inglés debido a que estudie en Inglaterra. Cualquier día de estos lo traduciré para que sirva de ejemplo para todos.



Parte Práctica: Programas de distintas implementaciones en Java y C++


Demostracion de File streams Input and Output

Este programa desarrollado en C++ y Java implementa una pequeña libreta de teléfonos donde principalmente se puede buscar, borrar, añadir, corregir contactos y notas. Este programa representa como se escribe y se lee de archivos usando estos dos lenguajes. También se demuestra el uso de information hiding, polymorphism, method overloading, garbage collection, generating output, getting input, formatting output, operators, Flow of control: Branching, Flow of control: Iteration y exception handling.

C++ Archivos File Streams I/O Java Archivos File Streams I/O
Click en la imagen para descargar

Demostración de Inheritance

Este programa desarrollado en C++ y Java produce el recibo de pago a un empleado. El empleado puede ser pagado mensual o por horas junto con los gastos de transporte que puede ser de tren o de coche. El pago puede también ser solo el pago de transporte o el salario. El pago es guardado en archivos que pueden ser editados usando notepad y así pueden ser guardados, imprimidos o borrados Este programa representa como inheritance es implementado en estos dos lenguajes. También se demuestra el uso de information hiding, polymorphism, method overloading, garbage collection, generating output, getting input, formatting output, operators, Flow of control: Branching, Flow of control: Iteration y exception handling, file streams Input and Output etc.

C++ Archivos Inheritance Java Archivos Inheritance
Click en la imagen para descargar

Demostración de Arrays

Este programa desarrollado en C++ y Java es una simple implementación de Arrays. Almacena jugadores y goles. Es hecho implementando dos arrays uno de jugadores y otro de goles. Un jugador puede ser añadido junto con sus goles. También pueden ser solo añadidos los goles a un jugador en específico. Este programa aparte de implementar Arrays también implementa encapsulation and information hiding, polymorphism, method overloading, garbage collection, generating output, getting input, formatting output, operators, Flow of control: Branching, Flow of control: Iteration, exception handling.

C++ Archivos Arrays Java Archivos Arrays
Click en la imagen para descargar

Programas para testar el rendimiento de Java y C++

Test Matemáticos Números Enteros

Para testar operaciones matemáticas en Java y C++ dos test fueron escritos los cuales son: división de números enteros y división de números reales con punto flotante. Este test realiza diez millones de divisiones de números enteros. Para calcular el tiempo system clock fue usado. Los resultados se pueden ver en el capitulo dos del proyecto.

Test numeros enteros C++ Archivos TestMatematicosIntegerJava.zip
Click en la imagen para descargar

Test Matemáticos Números reales con punto flotante (Float)

Este test realiza diez millones de divisiones de números reales con puntos flotantes. Para calcular el tiempo system clock fue usado. Los resultados se pueden ver en el capitulo dos del proyecto.

 Números reales C++ Archivos  Números reales Java Archivos
Click en la imagen para descargar

Tests de alocacion en memoria

Este test allocates y deallocates diez millones de veces un String en memoria .Para calcular el tiempo system clock fue usado. Los resultados se pueden ver en el capitulo dos del proyecto.

Test Alocacion en memoria C++ Archivos Test Allocacion de memoria Java Archivos
Click en la imagen para descargar

Test de File Streams Input and Output

Este test escribe cien mil números enteros a un file y los lee. Para calcular el tiempo system clock fue usado. Los resultados se pueden ver en el capitulo dos del proyecto.

Test File streams C++ Archivos Test File streams Java Archivos
Click en la imagen para descargar


Parte Teórica:Parte teórica del proyecto


Chapter 1


1. Pure object oriented programming languages

Object oriented programming is a modern way of programming. It is based on the concept of an object "a concept, abstraction, or thing with crisp boundaries and meaning for the problem at hand. Objects serve two purposes: they promote understanding of the real world, and provide a practical basis for the computer implementation" (Bennet 1999, p. 62). Operations on the objects are performed by methods which are common to all objects that are instances of a particular class. Object oriented programming has many benefits such as maintainability: less complexity in systems design and more user friendliness for the user; reusability which saves costs and time and it also useful for the development of complex systems. C++ and Java support object oriented programming. C++ "while not exclusively object-oriented, supports the paradigm through features that enable the programming of extensible abstractions" (Ghezzi & Jazayeri, 1998, p.285). Java was designed specially for object oriented programming.
A language to be considered as a purely object oriented should support several qualities:
1. Encapsulation/Information hiding
2. Inheritance
3. Polymorphism/Dynamic Binding
4. All pre-defined types are Objects (Booch 1996, p. 40).

1.1 Encapsulation/Information hiding
Encapsulation means "keeping together data and functions that belong together". Information hiding means "keeping the interface of the class separate from the details of its implementation." (Perry & Levin 1996, p. 361). Often people think that encapsulation and information hiding is the same. However, in both Java and C++ is possible to encapsulated data that is not hidden at all. "even though information may be encapsulated within record structures and arrays, this information is usually not hidden "(http://www.toa.com/pub/abstraction.txt).
In C++ and Java the class defines the data structure and includes the methods and functions that operate in this structure: this is encapsulation. They also provide access control which means that data can be private, public or protected. Data can only be access through the method(s) declared for the object: this is information hiding. It cannot be accessed by any other way. "The external interface of an object does not tell the world details of how data is stored or what algorithm is used by a method" (Britton & Doake 2000, p. 21). The main advantage of data hiding is that it provides ease of maintenance of the code. For instance, using the example below, it is possible to change the implementation of how a note is added without modifying the interface. C++ and Java have similar rules for methods and access control. However, the syntax for access control is different in the two languages.
In Java everything is modified with a control access keyword; C++ uses the following structure:
class note{
private:
char message[200]; //private data
public:
void addnote(]); //method to add note to a contact
void deletenote();
};


In Java the declaration is different:
public class note{
public void addnote() { }
public void deletenote(){ }
}

Encapsulation and information hiding is very useful for the programmer because they provide a "technique for packaging the information in such a way as to hide what should be hidden, and make visible what is intended to be visible." (http://www.itmweb.com/essay550.htm).

1.2 Inheritance
"One of the major goals of object-oriented program development is reuse of analysis, reuse of design, and reuse of both interfaces and implementations of code. One of the most important features of C++ for supporting reuse is inheritance" (Perry 1996, p. 544). Inheritance is a powerful tool where new classes (derived classes) can be created from another class called the base class. The derived class inherits all the attributes and functions of the base class and it is possible to add new features as needed. C++ and Java define the base class in the same way as it was a normal class. The following section of code demonstrates what a parent class looks like in C++:
class Employee{
string name; //private data
string surname;
public:
Employee(); //method to get employee
Transport *t; //link to transport
Employee(string na,string sur); //constructor
void getmenu(); //menu to change to transport payment
};


However the languages are different in the way the define a derived class. C++ uses colon (:) and Java uses extends to access the private data of the parent class. If these modifiers were not included in the definition of the derived class it would be impossible to access the private data of the parent class.
In C++ it looks like:
class Salaryemployee:public Employee

The same example in Java:
public class Salaryemployee extends Employee

Another difference is the way the derived class access the methods and attributes of the base class. In C++ there is no need to declare members of the base class for the derive class to have these members. The derived class gets these inherited members automatically without the programmer doing anything. A derived class inherits all the member functions that belong to the base class, e.g:
class Salaryemployee:public Employee //salaryemployee inherites from employee{
double monthlysalary; Derived class private data
public:
Salaryemployee(); //method to get salaryemployee private data
Salaryemployee(string na,string sur, double monthly); //constructor
};

Within the derived class Java has a keyword called super which is used to call the base class constructor. super has to be the first statement executed inside a subclass constructor. C++ does not need a keyword, i.e.:
Salaryemployee(String name, String surname, int monthlysalary) {
super(name,surname); //employee private data
monthlysalary=monthlysalary;}

C++ supports multiple inheritance. In contrast, Java does not. Schildt (2001, p. 267) says that "in Java you can specify only one superclass for any subclass that you create. Java does not support the inheritance of multiple superclasses into a single subclass. This differs from C++, in which you can inherit multiple base classes. You can, however, create hierarchy of inheritance in which a subclass becomes a superclass of another subclass. Of course, no class can be a superclass of itself."
The reason that Java designers omitted multiple inheritance was because of its complexity. Instead Java use interfaces to allow "an object to inherit many different method signatures with the caveat that the inheriting object must implement those inherited methods". (http://www.javaworld.com/javaqa/2002-07/02-qa-0719-multinheritance.html).
An interface is "ultimate abstract class that consists of public abstract methods and public static final fields" (Chew 1998, p. 159). This means that it does not contain implementation details of the methods. This is illustrated in the example below. Multiple inheritance syntax in C++ is very similar to single inheritance the only difference is that instead using a colon (:) it uses a comma (,) :
class Traveling employee : public Employee , public Transportation { …..}
Implementation of multiple inheritance


In Java first the interface to be implemented is declared:
interface Transportation
{
public void travel();
}


Then the inheriting class is subclassed from one class but it can implement multiple interfaces. To implement the interfaces the keyword implements followed by the name of the interfaces. If there are more interfaces to be added, then they will follow the implements keyword delimited by commas.
class traveling employee extends Employee implements Transportation {
…..
Public void travel { Implementation of the interface methods here }
…...
}


1.3 Polymorphism / Dynamic binding
Polymorphism "literally means 'an ability to appear as many forms', and it refers to the possibility of identical messages being sent to objects of different classes, each of which responds to the message in a different, yet still appropriate way" (Bennet, McRoob & Farmer 1999,p. 74). This means that the same message can be applied to different objects and each of the objects could use different methods to execute it, which method is applied depends on the object used.
Java and C++ support polymorphism. However, in C++ polymorphism must be designed into the classes. In Java, polymorphism is a default feature of its classes.
In C++ polymorphism appears in three different forms. The first is operator overloading, the second form is to create templates for groups of functions or classes and the third form is virtual functions. Operator overloading means "creating a new function with the same name as another function in the same scope so that it can be invoked with different type arguments" (Perry & Levin 1996, p.616). For instance, the + add operator can be add different types of numbers:
int operator+(int, int)
double operator+(double, double)
or the = = can compare different types of arguments:
char operator = =(char,char)
bool operator = = (int,int)

Operator overloading is mostly used for comparing strings, calculation of complex numbers, arithmetic and fractions calculations and input and output.
Templates are another form of polymorphism in C++ they "allow you to define functions and classes that have parameters for type names. This will allow you to design functions that can be used with arguments of different types" (Savitch 1999, p. 750).
Templates can be used with function and with classes. A function template, in most cases permits the program to declare a function which will work with all the parameter types rather than defining one function for every type. For instance, declaring one function template for swapping values,
template < class T > T means any type
void swap values(T& variable1, T& variable2) {…..}


All types of variables can be applied e.g. char, int , double, long, float.
swap values(integer 1, integer 2);
swap values (double 1, double 2);
swap values (char 1, char 2);
A class template is similar to a normal class. A class template "shows the compiler how to generate an actual class definition and the member function definitions when an object of the class template name is defined" (Perry & Levin 1996, p.621). A class template is for classes what a function template is for functions. Therefore, a class template is used with different arguments, int, double etc.., that share the same implementation.

Virtual functions "Dynamic binding, the ability of an object to respond to the same message in several ways depending on the context, is achieved through inheritance and virtual functions" (Perry & Levin 1996,p. 631). Virtual functions allow the derived class to replace the implementation of the base class. "A pointer to a derived class object may be assigned to a base class pointer, and a virtual function called through the pointer. If the function is virtual and occurs both in the base class and in derived classes, then the right function will be picked up based on what the base class pointer "really" points at." (http://www.glenmccl.com/virt_cmp.htm). When virtual functions are used the compiler creates a virtual function table pointer, this table represents the real type of the object. With virtual functions the programmer does not need to know what type of object may receive a particular message. For instance, a program is designed to output a message when a mammal is called. First we declare the base class i.e.
class mammals{
....
virtual void mammals() { cout<<"I am a mamal"}
…..}

Declaration of the derived class:
class human:public mammals{
….
void mammals(){cout<<"I am human">>endl;
….}

If the function mammals, in the base class, were not virtual, the output when human was called would be "I am a mammal". However, being virtual the output was "I am human" replacing the implementation of the base class.
Virtual functions are powerful features. There is not need to write complicated if or switch statements because "the object simply looks up its implementation in the virtual function table and calls it" (Chew 1998, p. 147).
In Java polymorphism is implemented differently. Java does not have the virtual keyword, because dynamic binding or method lookup is built into each class.
Forms of polymorphism found in Java are: method overloading and method overriding.
Method overloading is the same in Java and in C++. "It is possible to have two or more methods of the same name but with different arguments lists. The compiler knows which implementation to call by argument matching" (Chew, 1998, p.76). Method overloading is usually used to create methods with the same name which perform different task on different data types.
Because methods have the same name the Java compiler "uses longer 'mangled' or 'decorated' names that include the original method name, the types of each parameter and the exact order of the parameters to determine if the methods in a class are unique in that class".(Deitel 2001, p. 290). For instance, using the example bellow the compiler in the int add might use add of int and int and in the double it might use add of double and double to distinguish them.
The only requirement for overloading is that every method declares a different set of arguments. For example:
int add(int a, int b)
{
return (a+b)
}
double add(double a, double b)
{
return (a+b)
}

It would not be possible to have double(int , int) because the function would be looking for doubles not for integers:
double add(int a, double b)
{
return (a+b)
}

Method overriding
Method overriding is the same as virtual function in C++ with the only difference that "In Java method overriding is default; in C++ you have to ask for it" (http://www.wdvl.com/Authoring/Scripting/Tutorial/java_overloading.html).
For example, the mammal's example, used above in C++ for virtual functions, in Java would be defined as a normal inheritance class without having to modify the code, as in C++ declaring the function as virtual, e.g.:
public class mammals{
…..
public mammals() { System.out.println("I am a mammal");}
…..}

Declaration of the derived class is done in the following way:
public class human extends mammals{
….
public mammals(){System.out.println("I am human");}
….}

Polymorphism in Java is much easier to implement than in C++. In Java "polymorphism is integrated throughout the language because all Java identifiers are dynamically bound and are potentially polymorphic. This makes polymorphism a natural part of the Java language that makes it unnecessary for the developer to think about using polymorphism."
(http://www.frostburg.edu/dept/cosc/htracy/cosc390/LM7Polymorphism/PolymJava.html).

1.4 All predefined types are objects
In Java and C++ not all predefined types are objects. Predefined types that are not objects in Java and C++ are primitive types e.g.:
" Integers, such as byte, short, int, and long
" Floating-point numbers, such as double and float
" Characters representing letters and numbers called char
" Boolean, which is a type that represents true or false values.
(http://developer.java.sun.com/developer/onlineTraining/new2java/divelog/part1/page4.jsp)
However, Java to keep its object oriented nature and consistency uses wrapper classes to encapsulate or wrap primitive, simple types. The type wrappers are "Double, Float, Long, Integer, Short, Byte, Character and Boolean. These classes offer a wide array of methods that allow you to fully integrate the simple types into Java's object hierarchy" Schildt 2001, p. 419).
Wrapper classes are very useful because it is possible to convert the primitive type into an object so allowing invoking a method that requires an object type.
These methods change a numeric value read as string into its correct internal format. For example to create an integer object:
int x; x = Integer.parseInt(str) convert string to int : Creates an integer object

1.5 Summary
According to the four conditions listed above neither Java nor C++ are pure object oriented programming languages. C++ was designed with the object oriented paradigm in mind. C++ is the object oriented version of C. C++ is a multi-paradigm language; one of the paradigms it supports is object orientation. Thus, C++ can not be cataloged as a pure object oriented language.
However, most programmers agreed that this is an advantage because they can use the same language for different needs instead of having to apply different programming languages. According to Bjarne Stroustrup:(http://www.research.att.com/~bs/oopsla.pdf), creator of C++, "C++ was designed to support a range of styles that I considered fundamentally good and useful. Whether they were object oriented, and in which sense of the word, was either irrelevant or a minor concern". According to him C++ supports: 1. Abstraction, 2. Encapsulation, 3. Polymorphism, 4. Inheritance, covered in this report and object oriented principles. In addition to this C++ supports:
5. Genericity is the ability to parameterize types and functions by types and values, a powerful tool for general algorithms. 6. Coexistence with other languages and systems, essential for real world execution environments 7. Run time compactness and speed. Essential for classical systems programming 8. Static type safety. An integral property of language of the family to which C++ belongs and valuable both for guaranteeing properties of a design and for providing runtime and space efficiency. (http://www.research.att.com/~bs/oopsla.pdf ).

On the other hand, Java is considered to be a pure object oriented language, even though it fails to meet one of the principals: this is all predefined types are objects. However, "Java has no functions and no variables that can exist outside of class boundaries. Thus, all Java programs must be built out of objects." (Budd 1998, p.23). Java forces programmers to write programs in object oriented structure. Therefore, it can be considered as a pure object oriented language, everything is an object.

Chapter 2

2. Performance
People often make the assumption that Java is slower than C++ "because Java was developed to allow Java programs to run on multiple platforms" (http://www .javaworld.com /javaworld/jw-02-1998/jw-02-jperf.html). This supposedly makes Java slower. In contrast to C++, Java programs were compiled into an assembly language for an imaginary machine called the virtual machine. These assembly language instructions are called bytecodes. "Any machine that supports Java programs would provide a simulator, an interpreter that would read the bytecode values and execute them. In this fashion, any type of computer could be used as a virtual Java machine". (Budd 1998, p. 24).
Nevertheless, the problem with interpreters is that they are much slower than conventional compilers like C++'s one. Because of these reasons Java designers introduced the just-in-time (JIT) compiler. A JIT compiler reads the machine-independent bytecode representation of a Java program and before the program is run translates the bytecode into the specific system machine code the program is being executed. Therefore, Java programs "can be almost as fast as programs compiled in more conventional languages for the specific hardware platform, and still retain the portability of the virtual machine". (Budd 1998, p.24).
Another fact that could make Java slower than C++ is it's built in garbage collection mechanism (see later).

2.1 Performance implications
There are several implications that could influence in Java or C++ performance, apart from garbage collection and the ability to cope with multiplatforms, and these are executable size, selective loading and code optimization.

2.1.2 Executable size and selective loading
This project has not been focused on the Internet or Intranet. However, it has to be mentioned that Java was designed with the Web in mind. Any Java application can easily be delivered over the Internet, or any network, without operating system or hardware platform compatibility issues" (http://java.sun.com/java2/whatis/). This makes Java to perform better than native applications, such as C++ or C. The main factors for these differences are executable size and selective loading.

The executable size is determined by different factors. Firstly, binary code, used by C++, occupies more space than the bytecode used by Java. Secondly, Java incorporates a series helpful libraries such as mathematics, network, graphics etc. On the other hand, C++ does not, so these libraries must be implemented in order to be used. C++ uses application programming interfaces (APIs) "unfortunately, if a developer wants to use any special functions outside the core C++ API, he must deliver the implementation of the supporting libraries with his program. The inclusions of these libraries can double or even treble the size of delivered code" (http://www.javaworld.com/javaworld/jw-02-1998/jw-02-jperf-p2.html).

Selective loading is the way the Java loader loads classes as they are needed. This means that a program can be running but not using all its features until they are called thus saving megabytes of space. Nevertheless, C++ loaders load the whole executable file before executing it. This means that it loads classes which might be not used making the executable incredibly big. Therefore, for internet based applications, where one of the most important things is the download speed, Java is the language to be used.

2.1.3Code optimization
C++ compilers can improve programs performance by detecting deficiencies in the code and improving them e.g., dead code elimination, loop invariant hoisting, common subexpression elimination and constant propagation. In contrast, in Java a JVM compiler without JIT executes the code as it sees it so it cannot perform this kind of improvement. On the other hand, a JIT compiler is similar to a C++ one because it does JIT compilation and run-time optimization. "When Hotspot, JIT compiler, recognizes that a particular set of cached machine code is being executed numerous times, it will analyze that code and attempt to generate an optimized code section to replace the original." (http://www.basis.com /advantage /mag-v4n3/brew_java.html).
Even though Java JIT compilers have improved code optimization it will never be as fast as C++. A new JIT compiler JRE 1.3 has been designed focusing on code optimization "The JRE 1.3 includes the Hotspot Just In Time (JIT) compiler, which is both a JIT compiler and a run-time code optimizer. It is through Hotspot technology that Java is approaching the execution speeds of C/C++." (http://www.basis.com/ advantage/mag-v4n3/brew_java.html)

2.2 Tests
When a program, whichever language is used, is run in a computer it must perform these functions: (http://www.javaworld.com/javaworld/jw-02-1998/jw-02-jperf.html)
1. Load Program Executable
2. Run Program Instructions
3. Allocate Memory
4. Access System Resources


How the four functional groups in C++ programs are handled on the Windows NT operating system.




How the four functional groups are handled by the Java architecture.


Analysing the diagrams we can see that Java has to perform more operations than C++ to get the same result: this is the execution of the program. By looking at the diagrams it is possible to build up a view of the difference in performance between Java and C++: more operations and time are required by a Java program. However, theory is not practice.
The author, to test the languages performance in practice, wrote different tests:
1 A series of mathematical loops operations
2 File streams input and output
3 Memory allocation

These tests were performed in the following environment:
Operating system: Windows XP pro
Machine: Toshiba satellite 1670 CDS
Processor and memory: Pentium II 550 MHZ, 160 MB RAM
Java Software: JavaTM 2 Platform, Standard Edition (J2SETM )
C++ Software: Borland C++ version 5.1

2.2.1 Integer and Float division tests
To test mathematical operations in C++ and Java two tests were performed: these are integer division and float division. This test performs ten million times an integer and a float division. To calculate the time system clock was used. The test was executed ten times and the results are an average of them.

Test Java Time (secs) C++ Time (secs)
Integer division 0.23 0.21
Float division 0.22 0.22

This tests show that there is not a real difference between Java and C++ in these operations. Because primitive data types in Java are not objects "it should provide a reasonable best case baseline for comparing Java and C++ performance". (http://www.sosnoski.com/Java/Compare.html). This is due to the fact Java primitive types, integers and floats are stored in the stack, everything else is stored in the heap. Allocating memory in the stack is faster than on the heap.
It is important to notice that built in type's size in C++ can vary depending on the machine the program is running on. They are hardware dependent. In contrast, Java primitive types are fixed size so they are platform independent. "The predictability of the sizes for the primitive types makes Java programs highly portable". (Chew 1998, p.21).
The basic C++'s integer types are char, short, int and long. Java has the same integer basic types plus byte type.

Type Java size (fixed) C++ size (hardware dependent)
char 16-bit unsigned integer 1 byte
short 16-bit signed 2 bytes
int 32-bit signed 2 or 4 bytes (vm)6
long 64-bit signed 4 or 8 bytes(vm)
byte 8-bit signed No in c++

The floating types in C++ include float, double and long double. Java does not have long double.

Type Java size (fixed) C++ size (hardware dependent)
float 32-bit IEEE 754 double precision 4 bytes single precision
double 64-bit IEEE 754 double precision 8 bytes double precision
long double Not in Java 12 or 16 (vm)

2.2.2 Memory allocation test
Programs to perform calculations and store information must allocate memory. When the program is finished or the program does not need the information stored, memory must be given back to the system.
One of the most important differences between Java and C++ is the way they manage memory. Java has an built in garbage collector8 which "takes care of returning memory to the heap for objects that go out of the scope" (Chew 1998, p.80). An object goes out of the scope when it is not needed anymore by the program.
C++ does not have a garbage collection mechanism and programmers have to explicitly release memory back to the system. This test allocates a million times a string in memory and releases back. To calculate the time system clock was used. The test was executed ten times and the results are an average of them.

Test 1 Java Time (secs) C++ Time (secs)
Memory management 0.20 2.96


Because of the difference in time another test was executed. This time instead of using one word a whole sentence was used. This sentence was: I am trying to execute these test to see which one is faster Java or C++?. The result was:

Test 2 Java Time (secs) C++ Time (secs)
Memory management 0.21 4.72

It takes almost the same time for Java to allocate and deallocate a word as a sentence. In contrast C++ almost doubles the times. The author was expecting C++ to be faster than Java. However, Java is, in this test, relatively much faster than C++. Why? C++ when allocates memory does two operations:
1. Looks for right size slots of memory and then returns a pointer
2. This pointer is pointing to a random place (http://www.idiom.com/~zilla /Computer/javaCbenchmark.html)

On the other hand, because java has a built in garbage collector the allocator does not need to look for memory space because it knows where it is. In addition, the mechanism returns the last piece of memory requested by the user. This is a speed advantage because it is almost impossible that a program will miss the cache, thus speeding up the interaction. However, sometimes in bigger system the built in garbage collector can be a problem because it occupies double space than C++ that is done manually. "A larger memory footprint increases the probability that parts of the program will be swapped out to the disk. And swap file usage kills the speed like nothing else." (http://www.jelovic.com/articles/why_java_is_slow.htm)

2.2.3 File stream input and output test
These tests were performed to compare basic file operations in Java and C++. The next test writes 100.000 integer numbers to a file and reads them back. To calculate the time system clock was used. The test was executed ten times and the results are an average of them.

Test Java Time (secs) C++ Time (secs)
File input and output 5.05 1.65

The biggest difference in these tests between Java and C++ is this one. Java file input and output 10 streams work in a different way to C++ one's. In Java "Unlike the C++ streams, the Java file streams have no useful operations to read or write data. You must specify an adapter". (Horstmann 1997, p.327). In the author's opinion, Java since its appearance in the programming world has been improved as a programming language but little has been done to improve file input and output performance.
Programmers have developed strategies to overcome this Java disadvantage. For instance, according to Xu (http://www.cs.wisc.edu/~guo/projects/cs736/cs736 report.doc) there are several rules to speed up Java file input and output:
1. Avoid accessing the disk
2. Avoid accessing the underlying operation system
3. Avoid method calls
4. Avoid processing bytes and methods individually

Another solution to improve Java I/O performance programmers have adopted is to use native methods. A native method is a program written in another language, commonly C, called from a Java program. This is done by using JNI (Java Native Interface). "There are situations where Java alone does not meet the needs of your application. Programmers use the JNI to write Java native methods to handle those situations" (http://java.sun.com/products/jdk/1.2/docs/guide/jni/spec/intro.doc.html#16635).
Native methods are not difficult to implement and improve Java programs performance but the program looses portability, safety and maintainability. "System calls are cheap in Java native methods, while the overhead of calling native methods is rather high" (http://www.cs.wisc.edu/~guo/projects/cs736/cs736_report.doc).

2.3 Summary
Based on these results Java is slower than C++. However, in theory Java should be faster than C++ because firstly, Java's garbage collection mechanism, as explained in test 2.1.2, should make Java faster than C++ and secondly, run time compilation "Modern Java virtual machines do some amazing things: they profile the program while it is running, determine which parts to optimize, compile them, then uncompile and recompile them if new classes are loaded that override methods that were inlined!" (http://www.idiom.com/~zilla/Computer/javaCbenchmark.html).
Nevertheless, nowadays putting that in practice C++ is faster than Java. With its current features Java is not suitable for high performance software but it is suitable and reliable for small and medium sized software. In the developer's opinion, one of the main issues for improving performance that programmers and researchers do not discuss as much as compilers performance is how the program is written. It is obvious that well-written code would perform better than bad-written code and it would make a huge difference in a language performance.

Chapter 3



3. The basics of the languages

3.1 Char type
char in C++ is represented by a single byte. With this single byte it is possible to represent a maximum of 256 characters. In contrast Java uses Unicode, which instead of one byte,like C++, it uses two. It is possible to have up to 65,536 characters. Unicode "can encode both regular ASCII11 characters and most written language used today. A large fraction of the code is devoted to the Chinese, Japanese, and Korean script. To display and print foreign characters, the operating system must also support Unicode and have the necessary fonts installed" (Horstmann 1997, p. 196).
Java and C++ share some characters as the '\' or backslash character. It is used as an escape character to help represent special characters, such as the backspace, new line, single quote and double quote. They also share characters as \n - new line, \r - carriage return, \b - backspace, \t - tab, \' - single quote etc.

3.2 Boolean type
A Boolean expression is any expression that is either true or false. It is used for comparisons. C++ did not have a Boolean built-in type. It was necessary to define it:
#define FALSE 0
#define TRUE 1


Due to the limitations and inconsistencies of this method the ISO/ANSI committee which is a "voluntary, nontreaty organisation founded in 1946, responsible for creating international standards in many areas, including computers and communications. Its members are the national standards organisations of 89 countries, including the American National Standards Institute." (http://burks.brighton.ac.uk/burks/foldoc/index.htm), introduced the built in bool type to C++. It is an integral type, value 1 is true and value 0 is false.
Java has boolean type built-in. It only has two values true or false. Java Boolean is not an integral type as C++ and it is defined as:
boolean test = true

The Boolean operators of type bool are :
&& - (and) true if both operands true
|| - (or) true if at least one operand is true
! - (not) true if operand is false
The Boolean operators of any built in type are: " <, >, <= , >= " == (equal), ! = (not equal) (Chew 1997, p. 24-27)
Boolean expressions are important for the programmer, they are used in conditional statements as if, switch statements, loops, they are used to simplify complex conditions and/or manipulate logic values more directly.

3.3 Arrays
An array is a collection of data items of the same type. One of the most important features of an array is that its contents can be easily manipulated. "The syntax for arrays in C++ is highly varied because of the conceptual relationship to pointers. In Java, there are no pointers and the whole scheme for declaring arrays is simplified" (Chew 1997, p. 42). This means that when declaring an array in Java no size is specified with the identifier. The new operator specifies the memory allocation for the array. This is because "Java stores the length of an array in the array variable Java can (and does) runtime array bounds checking. That is, if a program attempts to reference an array element that is beyond the bounds of the array, then an exception is generated and an error message is printed" (http://www.cse.ucsc.edu~charlie/classes/60g/spring97/notes /node63.html ).
In the following example 10 contiguous memory allocations are allocated for the array.
Player player[]=new Player[10]; //array declaration

On the other hand in C++ the array size has to be specified with the identifier, "The elements field within brackets [ ] when declaring an array must be a constant value, since arrays are blocks of static memory of a given size and the compiler must be able to determine exactly how much memory it must assign to the array before any instruction is considered." (http://www.cplusplus.com/doc/tutorial/tut3-1.html), i.e.:
Player *player[10]; //call to player class

One of the most common errors using arrays is array overruns. Java provides protection against it but C++ does not. Using the above example, an array of 10 players, if player[11] is defined the C++ compiler will not do anything, "the result of an illegal array index is that your program will do something wrong, possibly disastrously wrong and it will do so without giving you any warning" (Savitch 1999, p519). Nevertheless, Java would output an error message and gives the opportunity to correct the error and continue, e.g.:
java.lang.ArrayIndexOutOfBoundsException
at Mainplayer.main(Mainplayer.java:15)
Exception in thread "main"

In both Java and C++ processing an array means applying some kind of operation. This is usually done using a for loop, i.e..:
for (index=1;index<=5;index++)
{
player[index]=new Player(" "," "," "); //array declaration
player[index].getdetails(index); //get new player details score[index]=new Score(0); //call to score constructor
score[index].getdetails(index); //get new player details
}


4 Printing output
Java and C++ have different ways of displaying the information. However, they support type-safe linkage. This means that "the number of arguments, the type of each argument and the order of the arguments must match the argument list of the function (or method, as a function called in Java. If there is a violation of these rules, the compiler would flag the call to the function (or method) as an error". (Chew 1997, p. 13).
The output in Java is done by the use of a special stream class called System.out, as the standard output stream. System.out represents the PrintStream standard Java input-output. System.out is an instance of PrintStream. System.out is used in the following way:
System.out.println("Enter message: ");

Operator overloading is not possible in Java. However, there is one small exception to this and it is the use of the + string concatenation, i.e..:
System.out.println("HOURLY SALARY PAYMENT: "+rate+ " Pound(s)\n\n");

It is important to notice that when the string + operator is used in primitive types, in Java primitive types are not objects, like int, double or and array of char, the conversion toString is done using wrapper classes. Because primitive types are not objects wrapper classes are used in Java to keep its object oriented nature. They encapsulate or wrap primitive, simple types. The type wrappers are "Double, Float, Long, Integer, Short, Byte, Character and Boolean. These classes offer a wide array of methods that allow you to fully integrate the simple types into Java's object hierarchy" (Schildt 2001, p. 419).

Java does not have a method to manipulate output. Therefore, it takes a considerably amount of work to format output in console mode. The only solution to this is to create a class that can do this job. There is a class called IOS14 (Chew 1997, p. 271) which includes services for setting precision, settings field widths, text justifications and selection of numerical formats, e.g.:
IOS i=new IOS(); //class to manipulate output position
i.setWidth(50); //justification width
i.setJustify(IOS.RIGHT);
i.println(System.out,"CONTACTS BOOK"); //main menu
i.println(System.out,"-------------");


C++ like Java uses stream classes for output operations. "C++ performs input and output operations via streams. The stream type object associated with an input or output sequence of characters has methods that can process those sequences." (Perry & Levin 996, p.579). These characters are kept in a buffer, which is an array of characters, until they are processed.
C++ handles differently the way of displaying information. In contrast to Java C++ allows the overloading of operators, i.e.:
cout<<"TRAIN SALARY PAYMENT: "<< payment<<" Pound(s)"<< endl; //display train payment

The arrow notation << is called the insertion operator and it facilitates to write data. endl is known as a manipulator in C++. Manipulators are used to control the behaviour of streams in C++. endl inserts end of line into the internal buffer and pass the contents of the buffer to the output device. The other way of new line is '\n'.
C++ is more efficient and provides more support for formatted output than Java with the iostreams class libraries. It is easier to control how data is displayed within fields, control left and right justification, etc. There are many mechanisms depending on the compiler, for instance Borland C++ version 5.1, the compiler used in this project, contains the goto and the setw manipulator, e.g.:
gotoxy(28,25);cout<<"Enter KM : "<< endl; //enter km
cout<< setw(18)<< name;
cout<< setw(17)<< surname;
cout<< setw(23)<< team;


3.5 Getting input
Java's input mechanism relies on very complicated system of classes. "There is no direct parallel to the very convenient println() method, for example, that allow you to read various types of data entered by the user" (Schildt 2001, p.82).
The way data is read in Java is using System.in.read() from System.in stream which is the input object attached to the keyboard. "System.in refers to an input stream managed by the System class that implements the standard input stream". (http:// www.ecs.umass. edu/ece/wireless/people/emmanuel/java/java/io/firstencounter.html)
By default System.in.read() returns an integer so if a char want to be read it has to be thrown as char so a char can be read, i.e.:
char ch;
ch = (char) System.in.read() read a char with system.in.read()

Another problem with System.in.read() is that return has to be pressed before the characters are typed and transmitted to the program. "the fact that System.in.read is line buffered is annoying, when enter is pressed line feed sequence is entered into the input stream and these characters are left pending in the input stream until you read them" (Schildt 2001, p. 83). Therefore, before executing another reading, the characters may need to be read, so the input buffer is deleted and the next reading operation can be executed. Because of these reasons, most of the programmers tend to design their own classes for reading characters from the keyboard. For instance, Alan Keith Curtis, Principal lecture in computer science in Anglia Polytechnic University (Cambridge), wrote two classes to read values KBInput (see Appendix G) and WinKBInput. The differences between them are that WinKBinput provides a window prompt, e.g.:
System.out.println("Enter name: ");name=KBInput.readString(); read string
System.out.println("Enter Kilometers ");km=KBInput.readInt(); //enter kilometres reads integer


Input with C++ is done in a very similar way to output. The syntax is very similar but there are two differences. Firstly, cin is used instead of cout and the insertion operator points in the opposite direction >>. The manipulators, as endl, are used in the same way as with output, i.e.:
gotoxy(18,11);cout<<"Enter name: ";cin>> name;endl;

3.6 File Streams: Input and Output
"A stream is an abstraction that either produces or consumes information" Schildt (2001, p.386). Input and output means that input can be taken from a keyboard or from a file and output can be sent to a screen or to file. Input and output to a file is done by the use of a stream. C++ and Java support the use of streams and they have very similar potentials. However, each language uses different syntax to perform the operations.
C++ has two main classes ifstream for input file, and ofstream for output file. "File Stream is also part of the stream class hierarchy. Formatting and state information is maintained by the ios class. Translation is provided by istream and ostream, and ifstream and ofstream objects have the same capabilities" (Perry & Levin 1996, p.581).
In Contrast, Java handles differently file input and output. It also uses streams but it defines two different types. These are the original byte streams and the added character streams. Character streams are used to handle the input and output of characters; the most used are InputStreamReader and OutputStreamReader. Byte streams are used to read or write binary data and they are easier to handle when operating with files because "At lowest level, all I/O is still byte-oriented." (Schildt 2001, p. 387). Java most used byte streams are FileInputStream for input file and FileOutputStream for output file. They are declared in the following way:
ifstream instream; //read from file
ofstreamoutstream;//write to a file
FileInputStream inStream;//read from file
FileOutputStream out; //write to a file


6.1 Getting input
To get input from a file with C++, after defining the stream which calls the ifstream class, firstly, the file needs to be opened. This is done by a function called open("filename"). Secondly, to take the input from a file the >> operator is used. The reading operation is done line by line. This means that every new line or space the reader thinks that is a new variable. Therefore, to read a whole file, for example a whole sentence, a special function has to be implemented.
With the ifstream class any kind of data can be read without any modification to the reader. A char or an integer is read in the same way, although the variable that reads the data has to be declared as needed. Thus the program knows that is reading a char or an integer.
When the program is finished the file must be closed. "When reading, writing or consulting operations on a file are complete we must close it so that it becomes again available. In order to do that we shall call to member function close(), that is in charge of flushing the buffers and closing the file. Closing the file disconnects the buffer from the stream."(http://www.cplusplus.com/doc/tutorial/tut6-1.html), e.g.:
char message[200]; reader declared as char
instream.open("note1.txt"); //open note1 txt open file in this case note1.txt
instream>>message; //read message instream gets the data from the file
instream.close(); close the file
if (!instream) if the file does not exist or it cannot be opened
{
cout<<"FILE NOT FOUND"<< endl;
getch();}
instream.close(); closes the file


As with C++ in Java, after declaring the stream which calls the FileInputStream class, the file to be read needs to be opened. In contrast to C++ Java does not need the function open to open a file. It is opened using a constructor:
FileInputStream(String filename);

Another difference with C++ is the way Java reads from a file. It uses a series of classes. The easiest way to read data from a file is using InputStreamReader class which "is a bridge from byte streams to character streams: It reads bytes and decodes them into characters using a specified charset. The charset that it uses may be specified by name or may be given explicitly, or the platform's default charset may be accepted. The standard charsets supported by Java are US-ASCII, ISO-8859-1, UTF-8, UTF-16BE, UTF-16LE, UTF-16."(http://java.sun.com/j2se/1.4/docs/api/java/io/InputStreamReader.html).
After defining the class, characters can be read using the read method. It reads from the file and it returns -1 when the stream is finished. In contrast to C++, Java needs to declare the character type. To read a character it uses read(), and to read a string it uses readline().
Another difference is that with Java "if a method generates an exception that it does not handle, it must declare that exception in a throws clause". (Schildt 2001, p. 373). Thus, as Java does not generate an exception with I/O files and exception must be declared. The following example illustrates how exceptions are declared in Java for I/O files.:
try{
File inputFile=new File("1.txt"); //open file to read file to read
FileInputStream inStream =new FileInputStream(inputFile); open file
InputStreamReader in=new InputStreamReader(inStream); call to class
int ch=' ';
ch=in.read(); //read from file read character
}
catch(Exception e) //if something goes wrong display error message exception declared
{
System.out.println("Failed "+e);
};

3.6.2 Sending output
C++ operates with output streams in a similar way as with input streams. An output stream is managed by the ofstream class. In the same way as input, after defining the variable which calls the class, the file needs to be open and this is done using open("filename"). When the file is connected to the ofstream class the operator << is used to write data to it.
One of the differences with instream class is that is possible to send a whole line of data without having to declare any method. This is done by the used of the function gets(variable). The variable type has to be declared so the data is written in the correct format. As with input it is not compulsory to declare an exception. However, it is useful to do it. The following section of code demonstrates how to write to a file with C++:
outstream.open(file1); //open specific file file to write
gotoxy(2,22);cout<<"Enter note: "<< endl; //change note
gotoxy(2,32);gets(message);endl; //get the message gets a whole line of input
outstream<< message; //save message writes the line to the file
outstream.close(); closes the file


With Java, after declaring the variable which calls the FileOutputStream class, which is used to open the file, another class to write data is used. The most popular is PrintStream "this class has a series of overloaded print() and printl() methods for displaying Java built-in types as text" Chew (1997, p.242).
One difference between Java and C++ file input/output is the error model. In C++ the error model is simple "As soon as there is a problem, the stream object turns into a dead state. That is pretty hard to overlook because no further operations succeed on a stream bad state" (Horstmann 1997, p.347). In Java an exception has to be declared. Thus if there is an error opening or closing a file an error message is displayed. However, programmers do not agree which is the best method. Some agree that Java way is the best method. Others think that it is better to set the stream to a testable failed state as C++ and continue running the program. The conclusion to this is that different error handling exceptions are declared depending on the application. The following piece of code shows how to do it in Java:
FileOutputStream out; //write new message declare variable
PrintStream pe; declare how data is written
try
{
out = new FileOutputStream(file1); file
pe =new PrintStream(out);
System.out.println("Enter message: ");message=KBInput.readString();pe.println(message); //writemessage
}
catch(Exception e) Exception
{
System.out.println("Failed "+e);
};


3.7 Garbage collection
"One of the biggest differences between Java and C++ is that Java has a built-in mechanism called garbage collection. Garbage collection is a scheme to reuse memory when it is no longer referenced by any variable." Chew (1997, p. 10). This means that when programming in C++ the programmer must implement a destructor, garbage collection mechanism, to do a clean up explicitly calling the delete operator. Clean up means "when execution enters a function, the function's statically allocated local variables are created on the stack. When the function exits, these variables are popped off the stack and the memory they occupied is available for reuse."(http://cplus.about.com/library/weekly/aa072502b.htm). Thus the memory is released.
A destructor is a member that when an instance of the class passes out of the scope is called automatically, so it prevents memory leaks or programs to crash. An instance of a class pass out of scope when it has been executed and is not longer needed for the execution of the program.
A destructor in C++ has the same name as the constructor but the only difference is that it has a tilde at the beginning of the declaration ~ class name. Each class can have only one destructor.
In C++ if no memory is allocated dynamically it is not necessary to write a destructor because the destructor is called automatically. However, when memory is allocated dynamically a destructor must be called. Dynamically allocated memory is done by the use of new keyword. "The new operator returns the address to the start of the allocated block of memory and it must be stored in a pointer". (http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.6)
The following example illustrates the use of the new operator:
Addressbook *Bookstock[1];
Bookstock[1]= new Addressbook (….


It is possible to call the destructor from anywhere in a program using delete, e.g.:
delete Bookstock[1];

However, programmers have to be careful because "You should not explicitly call the destructor, since doing so won't release the memory that was allocated for the object itself. Remember: delete p does two things: it calls the destructor and it deallocates the memory". (http://geneura.ugr.es/~jmerelo/c++-faq/dtors.html#faq-11.10)
If the new operator is used in arrays, brackets [ ] have to be added to delete pointer expression.
Therefore, the memory can be deallocated and the destructor is applied in all the members of the array, i.e.:
for ( index=1;index<=5;index++){ //display players array creation
player[index]=new Player(" "," "," "); //call to constructor
playerr[index]->getdetails(index); //get player details
score[index]=newScore(0); //call to constructor
score[index]->getdetails(index) }; //get score details
delete [ ] player; Deallocates the memory for all the members of the array
delete [ ] score;


In inheritance destructors are not inherited "the reason for this is that each object of a subtype consists of multiple parts, a base class part and a subclass part. The base class part. The base class part and a subclass part. The base class constructor forms the base class part. The subclass constructor forms the subclass part. Destructors clean up their respective parts" (http://cplus.about.com/library/weekly/aa120502c.htm). The destructor does not have to be defined as it is implemented like the default destructor provided by C++. However, it is useful to define it to assure that the program will work correctly, i.e.:
class Salaryemployee:public Employee //salaryemployee inherites from employee
{……
public:
~Salaryemployee(); Subclass destructor declaration
………};
Salaryemployee::~Salaryemployee() Destructor implementation
{
cout<<"** SALARY EMPLOYEE DESTRUCTOR **"<< endl;getch();}


In Java, objects are created with the new operator and the memory is allocated for this object in the heap. Garbage collection definition is the same for C++ and Java. They free memory when it is no longer needed to prevent bugs and program crashes, but in Java a garbage collection algorithms have been implemented. This mechanism is called automatically when need it. These algorithms were designed to do two basic things. Firstly, they must detect the garbage objects. Secondly, they must retake the memory used for these objects so it can be used again. To identify if an object is garbage or not roots are used. Roots are defined to the objects when created. Objects that are connected to the roots are considered alive and objects that are not are considered garbage, because they are not longer needed for the execution of the program.
Although Java has this special mechanism for garbage collection, programmers can still use System.gc() or Runtime.gc() to call garbage collection at any time.

3.8 Exception handling
Most of the time programmers do not deal correctly with negative circumstances. This could lead to unexpected errors or simply the software will not work making difficult to determine the problem or to fix it.
There are many errors that can be encountered as user input errors, device errors or physical errors. Users errors could be wrong input of data or try to do an operation that it can not be done. Device errors could be disks errors, printers errors etc. Physical errors could be disk or memory full and component failures which could be wrong delivery of data or malfunction of the program.
To correct these errors exceptions are used. "Both C++ and Java support the transfer of control out of a problem situation by throwing an exception." (Horstmann 1997, p.424).
Exception handling in C++ is a recent addition to the language. It is very complicated and if it is not used correctly it can cause more problems rather than prevent them. "On the other hand, the Java language was born with exception handling is much easier and safer to use than equivalent from C++" (Chew 1998, p. 184).
Java and C++ exception handling mechanism are very similar. They share the same keywords throw, try and catch. Throw is used "When an error is encountered that it cannot be handled at the point of detection, an exception can be raised with the command: throw" (Horstmann 1997, p. 425). It is possible to throw an anonymous object to handle error rather than using a variable that is never used again.
try is used to handle exceptions. "The code may involve any sequence of statements, including loops or function calls. If anywhere during execution a stack error is reported, the code in the handler gains control" (Horstmann 1997, p.426), i.e.:
try {
code to be executed
}
catch (Exception e){
what to do if an error occurs
}


In C++ the most important use of the exception handling mechanism is the "stack walk". "The process of calling destructors on leaving a scope, compilers put in some initialization code to ensure that if a routine may return via an exception it will properly call destructors "(http://www.gamedev.net/reference/articles/article953.asp). This means that if an error is detected because of lack of memory it can be corrected using exception handling that automatically will call the destructors and clean that memory. In Java this is no necessary as it has an automated garbage collection mechanism.
Another difference between Java and C++ is that "in Java, a function must declare all explicit exceptions that it throws. In Java, the throws specifier is used to declare which exceptions a function can throw" (Horstmann 1997, p. 437), e.g.:
class note{
public void read(DataInputStream in) throws IOException
{
double s = in.readDouble(); can throw an IOException
}}


Java and C++ have very similar exception handling mechanism. However, Java has an improved and more reliable mechanism. Apart from in Java is compulsory to declare the exception mechanism to prevent errors during run time, "C++ exception specifiers are not enforced at compile time. Instead they are enforced at run time. If an exception is detected in a function that is not of the types listed in the specifier list, the program terminates" (Hostmann 1997, p.438) and this is an obvious disadvantage.


The project continues... if you want a full copy of it please email me.



 

Warning: include(/home/luiscorb/public_html/footer.php) [function.include]: failed to open stream: No such file or directory in C:\Inetpub\wwwroot\corbete\ArchivosTrabajos\proyecto.php on line 1366

Warning: include() [function.include]: Failed opening '/home/luiscorb/public_html/footer.php' for inclusion (include_path='.;C:\php5\pear') in C:\Inetpub\wwwroot\corbete\ArchivosTrabajos\proyecto.php on line 1366