| Prev | Next | Start of Chapter | End of Chapter | Contents | Glossary | Index | Comments | (6 out of 8)

Using Lists and Arrays to Represent Data Series

Your application might obtain certain attribute values by cycling through the values or items in a fixed-length array. Your application might also need to store an unknown number of values or items in a variable-length list.

You represent values and items in a series in G2 by using:


Note: If you create a quantity list or array, the list or array can contain a mixture of integers and floating point numbers. Similarly, if you create a value list or array, the list or array can contain a mixture of value types.

You typically create subobjects that contain lists and array, as this diagram illustrates:


Your application can dynamically insert items and values into and remove items and values from a list or array. Your application can also test whether an item or value is a member of a particular list or array as a condition for further processing.

This section discusses the various list and array classes from which you can create subclasses. It also provides guidelines for choosing one type of data representation over the other.

List and Array Class Hierarchy

Similar to variables and parameters, G2 provides build-in list and array classes that correspond to the basic data types.This figure shows the hierarchy of built-in list and array classes:


Creating a Subclass of List or Array

Just as you can create subclasses of the built-in variable and parameter classes, you can create subclasses of the built-in list and array classes. You would create a subclass of an item array, for example, if your application requires several instances of an array that contains the same class of items.

By creating subclasses of lists and arrays, you avoid having to initialize the attributes and element types each time an instance of the list or array is created. However, be aware that creating subclasses can degrade performance, depending on the type of operation.

When choosing the superior class for a list or array subclass, you should always choose the most restrictive class for the type of data. The exception to this rule is casting, explained in Use Casting When Binding Array Subclasses to Local Variables.

To create a subclass of list or array:

  1. Create a class definition whose superior class is one of the built-in G2 list or array classes.

  2. Specify Attribute-initializations for the class to initialize the Initializable-system-attributes, as needed.

You can initialize these system-defined attributes:

For efficiency, you should always specify the most restrictive item class in the Element-type attribute initialization of the item list or item array subclass.

Declaring an Attribute that Contains a List or Array

To create a subobject that is a list or array, specify the class-specific attributes to be an instance of one of the built-in list or array classes, or a subclass of one of these classes.

To declare an attribute to contain a subclass of list or array:

For example:

where permanent-item-array is a subclass of the built-in G2 class item-array.

Comparison Between Lists and Arrays

When you represent data in a series, you must think carefully about whether to use a list or an array. This table summarizes the differences between these types of objects in G2:

List Array
Efficient referencing, using an index
No
Yes
Efficient insertion and deletion operations
Yes
No
Type checking
Yes
Yes
Initial value
No
Yes
Can be variable length
Yes
Yes
Can check for duplicate elements
Yes
No
Can be permanent or temporary
Yes
Yes

The comparison in the table above regarding the relative efficiency of lists and arrays requires some explanation:

For very large lists, references to a specific element by its index, such as L[1000], are many times slower for lists than the equivalent array reference. The reason is G2 counts through the list element-by-element until it reaches the 1000th element.


Caution: Do not use references such as L[1000] to access the elements of a list, unless the list is guaranteed to have less than 500 elements.

Keep in mind that while your list might not currently contain more than 500 elements, it might in the future. Thus, you should always consider issues of scalability when choosing a data structure to represent serial data.

The exception to this guideline is accessing the first element of a list by its index when the list contains more than 500 elements. For example, list[0] is only slightly slower than the same reference for an array.

These operations are much more efficient for lists than for arrays:

Thus, the general guideline for choosing between lists and arrays is:

Use this data structure... To...
Array
Access specific elements by their index, which is often the case for numeric operations
List
Insert and delete elements at the beginning or end of the list or when the specific list element is known

For more information, see the references in this table:

For information on... See...
Casting
Use Casting When Binding Array Subclasses to Local Variables
Supporting data for efficiency conclusions
Appendix A, Benchmarking Results

Guidelines for Using Lists

Follow these guidelines when using lists.

Use Lists for Fast Insertion and Removal

You often need to maintain a list of items, when the number of items is not known or might vary significantly at run-time. For example, if you needed to maintain a list of messages that the application generates at run-time, you would use a list, because you rarely need to access a specific element by its index.

In cases where you cannot identify a specific item without referring to its index, you can perform fast insertion and deletion operations by using the insert at the beginning of or insert at the end of actions. If you can identify a specific item without referring to its index, for example, by using a relation, by iterating through the elements, or by using a unique identifier, you can also use the insert before and insert after actions to insert elements.

For additional information about list iteration, see Be Careful with List Iterations.

For more information about the performance implications of casting, see Effect of Subclassing, Stability, and Casting on Array References.

Choose the Most Restrictive Data Type

When choosing the superior class for a list subclass, you should always choose the most restrictive class for the type of data.

For a detailed explanation, see Use Strong Typing.

Guidelines for Using Arrays

If you determine that your application requires an array, follow these guidelines when using the array.

Use Arrays for Fast Access to Elements by Index

Due to the inefficiency of referencing list elements by index, you should almost always use an array if you need to reference or assign a specific element by its index. For example, you typically use arrays for fast numeric operations and matrix operations.

In addition, G2 supports a number of matrix operations through its system procedures, which add to the efficiency of arrays for matrix operations.

For more information about the performance of arrays, see Use Arrays for Fast Direct Access and Data Storage.

Always Change Array Elements, Never Conclude

Assigning values to an array is extremely fast when you use the change action. In fact, changing array elements is significantly faster than concluding attributes, parameters, or variables, and is almost as fast as concluding a local variable. However, concluding an array element is significantly slower than changing an array element, although they are functionally equivalent.


Caution: Never use the conclude action to change the elements of an array; always use the change action.

Beware of Manipulating Array Elements

When you manipulate the elements of an array, be aware of the following:

Choose the Most Restrictive Data Type

When choosing the superior class for an array subclass, you should always choose the most restrictive class for the type of data.

For a detailed explanation, see Use Strong Typing.

Use Stability Declarations for Value Array Subclasses

For maximum efficiency, when you create a subclass of any type of value array, you should declare the class stable for dependent compilations.

For information on declaring an array subclass to be stable, see Use Stability Declarations.

Use Native Arrays in Performance-Sensitive Code

Accessing values from a native array is faster than getting values from a subclassed array. Thus, you should use native arrays in performance-sensitive code. The difference between native and non-native lists is less significant.

Use Casting When Binding Array Subclasses to Local Variables

Casting is when you bind a local variable to a subclass of the local variable's type, as opposed to declaring a local variable explicitly for the subclass. In the case of arrays, this means declaring a local variable to be a native array class, and binding the local variable to an array subclass. Casting can improve performance under these circumstances:

If you use casting when you bind array subclasses to local variables, referencing an element of the array subclass is as fast as referencing a native array element.

This figure shows an example of binding a local variable with casting and without. In the first procedure, FA is declared to be a type of my-float-array. The procedure then creates an instance of my-float-array, which is the same type as the local variable. In the second procedure, FA is declared to be a type of float-array, which is a superior class of my-float-array. The procedure then creates an instance of the subclass and binds it to the local variable, using casting.


| Prev | Next | Start of Chapter | End of Chapter | Contents | Glossary | Index | Comments | (6 out of 8)

Copyright © 1997 Gensym Corporation, Inc.