CSC/ECE 517 Fall 2012/ch1 1w21 wi: Difference between revisions

From Expertiza_Wiki
Jump to navigation Jump to search
Line 182: Line 182:


Advantages that use of primitive data type offers are as follows:
Advantages that use of primitive data type offers are as follows:
===[Consistency][http://www.research.ibm.com/people/a/alpert/ptch/ptch.html]===
===Consistency===
Many of Java’s ideas originate in C++ and in C++, objects and primitive type also co-exist. When object-oriented constructs were grafted onto the C language, C’s data types remained as is. The motivation behind this is that Bjarne Stroustrup, C++’s designer, wanted to be as consistent as possible with the base C language, hoping to capitalize on programmers’ pre-C++ knowledge.
Many of Java’s ideas originate in C++ and in C++, objects and primitive type also co-exist. When object-oriented constructs were grafted onto the C language, C’s data types remained as is. The motivation behind this is that Bjarne Stroustrup, C++’s designer, wanted to be as consistent as possible with the base C language, hoping to capitalize on programmers’ pre-C++ knowledge.



Revision as of 01:47, 11 September 2012

Primitive objects in object-oriented languages

Introduction

In any programming language, the data type refers to the class of data which contains specific type or range of values. Data types are used along with variables used in the program. The data type tells us what kind of values the variable can store, what is the range of the values and how much space the values take in memory etc.

The primitive data types refer to the built-in data types which are supported by the programming language. Often 'data types' and 'primitive data types' are used interchangeably. But not all data types are primitive. Programming languages have some non-primitive data types or derived data types which are provided by the language by making use of its primitive data types.

The common built-in data types or primitive data types are integers, floating point numbers, characters, strings and boolean.

  • Integers - Integers represent the whole numbers which can be positive or negative or zero, e.g. 9999, 0, -25, etc.
  • Floating point numbers - Floating point numbers represent the numbers which are fractions or contain floating-decimal points, e.g. -3.002, 2.5, 22.0, etc.
  • Characters - Characters represent any single letter, number, space, punctuation mark, or symbol that can be typed on a computer, e.g. 'a', '9', ' ', '!' , '\n', etc.
  • Strings - Strings represent the sequences of characters or simply any text, e.g. "Hello!", "9 am to 6 pm", etc.
  • Booleans - Booleans represent the true or false values. Sometimes, instead of true and false, 1 and 0 are used to represent the boolean values.

Many object-oriented programming languages provide support for primitive data types while some object-oriented programming languages provide support for primitive objects along with primitive types.

Definition

Primitive objects refer to the objects of built-in classes which provide more functionality than the primitive types. Some object-oriented programming languages provide support for only primitive objects (i.e., in such languages all primitive types are objects).

Different object-oriented programming languages implement these primitive data types and primitive objects in a different manner.

Primitive objects in different OO languages

Java

In Java, there are 8 primitive types: boolean, char, byte, short, int, long, float, and double. <ref>http://www.cafeaulait.org/course/week2/02.html Java's Primitive Data Types</ref>

For each of these primitive types, Java provides wrapper classes to create primitive objects which wrap the primitive data values. A wrapper not only contains the primitive data value, but it also defines properties and methods that can be used to manipulate that data. In Java, the primitive values are not implicitly converted to primitive objects. Instead, methods are provided for doing explicit conversion. The primitive objects are stored on heap in memory while the variables containing primitive values are stored on stack.<ref>http://www.informit.com/articles/article.aspx?p=31755&seqNum=8 Stack and Heap memory</ref>

Primitive Type Wrapper Class Size
boolean Boolean 1-bit
char Character 16-bit
byte Byte 8-bit
short Short 16-bit
int Integer 32-bit
long Long 64-bit
float Float 32-bit
double Double 64-bit

Example:

   int i = 10;
   int ii = 20;
   Integer I = new Integer(i);
   Integer II = new Integer(ii);
   System.out.println(I+II);            
   System.out.println(I.equals(II));    

Output:

   30
   false


To find out if these wrapper classes are primitive or not, we can use the isPrimitive() method.

   System.out.println(INTEGER.TYPE.isPrimitive());
   System.out.println(BOOLEAN.TYPE.isPrimitive());

Output:

   true
   true


In Java, the comparison operations work in the same way on the primitive objects as well as any other class objects but different on the primitive types. The == operator when used on objects checks whether they refer to the same object but when used on variables of primitive types checks whether they contain the same value.<ref>http://leepoint.net/notes-java/data/expressions/22compareobjects.html Comparisons in Java</ref>

Example:

   int i = 10;
   int ii = 10;
   Integer I = new Integer(i);
   Integer II = new Integer(ii);
   System.out.println(I==II);            
   System.out.println(i==ii);

Output:

   false
   true

C#

C# is a strongly typed language, where it is necessary to declare the data type of a variable and also be aware of the data type conversion. C# provides a significant number of primitive data types.<ref>http://condor.depaul.edu/sjost/ndp/notes/cs1/CSDatatypes.htm C# Primitive Datatypes</ref><ref>http://www.java2s.com/Tutorial/CSharp/0040__Data-Type/PrimitivesinC.htm Primitives in C#</ref>

Because C# represents all primitive data types as objects, it is possible to call an object method on a primitive data type. For example:

   static void Main()
   {
       int x = 7;
       object o = x;
       System.Console.WriteLine(o.ToString());
   }

Some data types (e.g. Decimal and String) can appear like primitives at first sight, but are actually not. So it is important to exercise caution before making such assumptions. To test whether a particular type is a primitive or not you can use the property Type.IsPrimitive.

Consider the following example:

   if (t.IsPrimitive)    // where t is the type
   {
       // Is Primitive
   } else if (t == typeof(Decimal))
   {
       // Is Decimal
   } else if (t == typeof(String))
   {
       // Is String
   } else
   {
       // Other type
   }

JavaScript

There are 5 primitive data types in JavaScript: string, number, boolean, null and undefined. <ref>http://oreilly.com/javascript/excerpts/learning-javascript/javascript-datatypes-variables.html JavaScript Data Types and Variables</ref>

For string, number and boolean values, there are corresponding classes just like in Java to create primitive objects which wrap the primitive values.

Primitive Type Wrapper Class
string String
number Number
boolean Boolean

In JavaScript, the primitive value is implicitly converted to a primitive object whenever someone tries to access a property or invoke a method on the primitive value and the primitive object is used in place of the primitive value. Since the object contains properties and methods, the use of primitive value as an object succeeds. After the property is accessed or the method is processed, the primitive object is no longer needed and hence discarded. The same is true for the other primitive types and their corresponding primitive objects.

Example:

   var upperCaseString = "APPLE";
   var lowerCaseString = upperCaseString.toLowerCase();  // assigns string "apple" to lowerCaseString 
   var s = "Hello"
   var len = s.length;                                   // assigns value 5 to len

Ruby

Since Ruby is a pure object oriented language, everything in Ruby is an object. Hence, all primitive types such as integers, floating point numbers, strings, are objects of a built-in class.<ref>http://ruby-doc.org/docs/ProgrammingRuby/html/builtins.html Classes in Ruby</ref> All integers are primitive objects of either class Fixnum or Bignum. A numeric literal with a decimal point and/or an exponent is a primitive object of Float. Single quoted literals and double quoted literals are primitive objects of String.

Example:

   puts 10.class
   puts 7.45.class
   puts 'hi'.class
   puts "hello".class

Output:

   Fixnum
   Float
   String
   String

This indicates that 10 is converted into an object of type Fixnum, 7.45 is converted into an object of type Float, 'hi' and "hello" are both converted into an object of type String.

Since all primitive types in Ruby are objects, we should be able to call methods of the Object class on them. Let us demonstrate the same for integer and float using the following example:

   a=10
   puts a.to_f  
   b=20.5
   puts b.to_i

Output:

   10.0
   20

Advantages of primitives

Advantages that use of primitive data type offers are as follows:

Consistency

Many of Java’s ideas originate in C++ and in C++, objects and primitive type also co-exist. When object-oriented constructs were grafted onto the C language, C’s data types remained as is. The motivation behind this is that Bjarne Stroustrup, C++’s designer, wanted to be as consistent as possible with the base C language, hoping to capitalize on programmers’ pre-C++ knowledge.

Simplicity

It is simple and intuitive to use primitive data type in basic utility.

Example:

1. Recurring number in a loop.(C++)

  for(int i=0;i<10;i++)


2. Temp variables that record only one or two data.

Performance

Time

Processing primitive data type operation would be faster than processing composite data type in most cases. There are several reasons result in this differences.

  • Hardware processing discrepancy

Many primitive data operations (like integer addition) can be performed as a single machine instruction while processing of composite data type would be transformed to a combination of primitive data types. eg. Some processors offer specific instructions to process sequences of characters with a single instruction.

Example:

Difference in data fetching between primitive data and composite data in Java

  • Initialization overheads for composite data type

There are many initialization operations for composite data type. for example boxing and unboxing, constructors and destructors.

Composite data type like class will have allocation and garbage collection overhead that may be beyond the control of the programmer and can sometimes lead to performance problems. For example, commonly used stop-the-world garbage collectors, which pause program execution at arbitrary times, may make garbage collection inappropriate for some embedded systems, high-performance server software, and applications with real-time needs.In the early days of Java technology, allocating objects got a high overheads. There were lots of articles advising developers to avoid creating temporary objects unnecessarily because allocation (and the corresponding garbage-collection overhead) was expensive. Although the costs have been greatly reduced nowadays. It still much slower than primitive data type which don’t have such troubles.

Example:

       public class Test{
       double dur1,dur2;
       int N=100000000;
       public void test1()
       {
          int a=1,b=1;
          long startTime1 = System.currentTimeMillis();
          for(int i=0;i<N;i++){
             a=a+b;
                         }
          long endTime1 = System.currentTimeMillis();
          System.out.println(endTime1-startTime1);
       }
       public void test2(){
           Integer c=new Integer(1);
           Integer d=new Integer(1);
           long startTime2 = System.currentTimeMillis();
           for(int i=0;i<N;i++){
              c=c+d;
           }
           long endTime2 = System.currentTimeMillis();
           System.out.println(endTime2-startTime2)
       }

Average execution time for test1 is: 1 mm

Average execution time for test2 is: 702mm

(test case number: 1000 times )

Space

Composite data type will cost more memory space than primitive data type in general. The reason is not only for the overheads generated by constructors, destructors etc, but also the feature of data alignment. <ref>http://en.wikipedia.org/wiki/Data_structure_alignment#Data_structure_padding Data structure alignment</ref>

Example of data alignment (C++)

      struct compose
      {
          char name;
          int a;
          int b;
      }

We all know the size of char is 1 byte, the size of int is 4 bytes. But the size of the struct compose as shown above is 12 bytes but not 9 bytes.

Functionality

Discussion of advantages and disadvantages should concerned the functionality you want to implement. For example if you want to operate a serials of int number. The performance of array may be better than int. <ref>http://cs.smith.edu/~thiebaut/ArtOfAssembly/CH05/CH05-2.html composite datatypes</ref>

To access an element of an array, you need a function that converts an array index into the address of the indexed element. For a single dimension array, this function is very simple. It is Element_Address = Base_Address + ((Index - Initial_Index) * Element_Size) However, If you use five primitive data type to implement the same function. It may cost more time for the cpu to search the address of each data.

Conclusion

References

<references/>