Samstag, 5. März 2016

Sprachen in der Programmierung und ihre Anzahl

Dieses Dokument beschreibt die Thematik von Programmiersprachen. Es dient nicht einem Vergleich und nicht einer objektiven Einschätzung. Das Anliegen des Dokumentes ist es, den Sinn und Zweck von Sprachen in der Informatik zu beschreiben. Es werden grundlegende Gedanken erläutert, wie z.b. Was sind Sprachen? Wieviele Sprachen sind realistisch? Und wie realisieren wir eine mögliche Sprachlandschafe?
Zum Schluss wird eine aktuelle Tool-Chain genannt, mit der es möglich ist das Ziel der Sprachen zu erreichen.
Viel Spaß beim Lesen.

Sprachen in der Programmierung gibt es viele. Jede scheint ihre Berechtigung zu haben, doch wieviele Sprachen sind notwendig um korrekt zu modellieren?

Sprachen dienen dazu um im Computer zu modellieren bzw um ihn zu konfigurieren.
Am Ende wird auf eine Maschinencode-Ebene programmiert und konfiguriert. Letztlich steuert man den Elektronenfluss und wandelt einen elektrischen Input in einen Output um. Dabei wird der Input mit Sensoren aufgenommen und der Output durch Aktoren repräsentiert. Dazwischen gibt es viele unterschiedliche Features.
Features sind Merkmale, die die Translation des Inputs zum Output abstrahieren und so einen einfachen Umgang der Translation ermöglichen.
Generell kann man sagen, der Rechner besteht nur aus Bits, Transistoren und Kondensatoren. Die Bits kann man als Atome sehen, die Transistoren als Werkzeug und die Kondensatoren als Zeit. Raum ist derjenige, der benötigt wird um alle Transistoren, Kondensatoren und Leitungen zu platzieren. Demnach die Werkstatt.
Vielleicht werden Programmierer und Elektroingenieure daher als Bastler bezeichnet?

Was ist also eine Sprache? Wofür brauchen wir eine Sprache? Und warum brauchen wir eine Sprache?
Es ist so, dass der Rechner im Prinzip eine Touring-Maschine ist. Eine Touring-Maschine besteht aus einem Band, einem Alphabet und einem Schreiblesekopf. Die Daten stehen auf dem Band im Alphabet der Maschine geschrieben. Der Schreiblesekopf verarbeitet dann die Daten und schreibt sie wieder im Alphabet auf das Band. Oft an einer anderen Stelle des Bands. Das Band, d.h. der Speicher, bildet demnach auch einen Raum.
Doch was sind dann Sprachen?
Sie sind letztlich Features. Demnach dienen sie der Abstraktion und sind Werkzeuge der Logik. Logik ist wiederum eine Beschreibung um Gegebenheiten zu formulieren. D.h. auch eine Abstraktion. D.h. auch ein Feature. D.h. auch eine Sprache.
Es ergibt sich ein zyklischer Schluss. D.h. Sprachen formulieren Gegebenheiten.
"Du bist verheiratet" ist eine Gegebenheit. Sie ist aus anderen Gegebenheiten entstanden, wie z.B. Dass man sich kennenlernte.
Ist demnach alles eine Gegebenheit? Fast. Features, wie eine Sprache eröffnen eine neue Dimension. Eine Dimension, die nicht räumlich ist. Sondern kreativer, abstrakter und unendlicher Natur.
(Einstein: "Die Dummheit des Menschen und das Universum scheinen unendlich zu sein. Bei zweitem bin ich mir nicht ganz sicher.")
Sprachen dienen demnach der Kreativität, Abstraktion (als Feature) und Vielfältigkeit.

Somit ergibt sich die Frage des Blogs: Wieviele Sprachen sind notwendig?
Sprachwissenschaftler sagen: Jede Sprache, die aktuell von Menschen auf der Erde gesprochen werden, sind gleichwertig. D.h. es lässt sich in jeder Sprache den gleichen Gedanken in ähnlicher Effizienz, Effektivität, Robustheit und Transformität formulieren. Effizienz im Sinne von zeitlicher Geschwindigkeit, Effektivität im Sinne von vergleichbaren und gleichem Ergebnis, Robustheit im Sinne von Fehlerkorrektur und Transformität im Sinne von vielfältigen Variationen.
Sind alle Sprachen gleichwertig, so brauchen wir nur eine.
In der Informatik spricht man dabei von touring-vollständigen Sprachen.
Jetzt ist es jedoch so, dass wir weder wissen, ob uns ein Feature fehlt, in dem Touringmodell, noch wissen wir, ob wir alle erreicht haben.
In Prognosemodellen wissen wir, dass die Anzahl der unbekannten Variablen immer größer ist als die berücksichtigten.
Daher Sprechern wir mehr als eine Sprache.

Was heißt das in der Praxis?
Wie brauchen alle Sprachen, soweit sie sich deutlich unterscheiden. Deutlich unterscheiden bedeutet wiederum, sie müssen in ihren Wörtern, die Features präsentieren, so unterschiedlich sein, dass die Schnittmenge signifikant kleiner ist als die gesamte Anzahl der Wörter. D.h. die Schnittmenge sollte 80% nicht übersteigen. Konkret wäre das beste sie hätten keine Schnittmenge. Dann benötigen wir "beide" Sprachen.
Die Anzahl der notwendigen Sprachen ist somit abhängig davon, wie unterschiedlich sie sind. Wenige unterschiedliche Sprachen sind gleichwertig, zu vielen gleichen Sprachen. Zusätzlich zum Unterschied der Sprachen, ist die Anzahl der "notwendigen" Sprachen, abhängig von der Anzahl der Features (Worten unterschiedlicher Bedeutungen innerhalb der Sprache).

Im Chinesischem gibt es unterschiedliche Dialekte. Jedoch sind die Schriftzeichen gleich. So haben wir damit schriftlich die gleiche Bedeutung, jedoch sprachlich unterschiedliche Laute.
Dass bedeutet, dass im schriftlichen sich die Features zu 100% überschneiden, was tendenziell dazu führt, dass die Dialekte von der Bedeutung gleich sind, wir also keine weiteren Features gewinnen indem wir einen weiteren Dialekt lernen. Die gesprochene chinesische Sprache ist trotz ihrer Dialekte tendenziell gleich, da die Bevölkerung anhand der Zeichen weitere Bedeutungen lernt (insbesondere fachliche), so dass, trotz unterschiedlicher Laute, die gleiche Bedeutung entsteht. In anderen Sprachen ist es mit den Dialekten äquivalent. Auf die Theorie bezogen schließen wir, man erlangt keine weitere Dimension durch einen Dialekt.
(Ausnahme entsteht, wenn der Dialekt auch geschrieben wird, denn dann entsteht tendenziell auch eine andere Bedeutung. Bsp Servus vs. Tschüß und ciao. Servus soll herzlicher sein als Tschüß und ciao in Deutschland cooler.
Das zeigt auch, dass für gesprochene Sprachen die Bedeutung immer ortsspezifisch ist. Was bedeutet, dass alle gesprochenen Sprachen gleich wichtig sind zu lernen.)

Bei der Informatik kann man zum Glück reduzierter bleiben.
Geht man davon aus, man verwendet nur Sprachen, die sich in ihren Wörtern zu mindestens 20% unterscheiden. (da 20% der Breite der gaussschen Normalverteilung für nicht signifikante Abweichungen um den Erwartungswert entspricht), ergibt sich die Anzahl der "notwendigen" Sprachen anhand der existierenden Features.
Für Features gilt das gleiche wie für Sprachen, sie müssen sich in ihren Eigenschaften zu mindestens 20% unterscheiden.
Das praktisch zu betrachtene Feature ist atomar. Hat also nur eine Eigenschaft.
So ergibt sich die Anzahl der notwendigen Sprachen in der Informatik zum aktuellen Zeitpunkt hier Vorort und im Sinne der möglichen Verwaltung, anhand der atomaren Features der verwendeten Sprachen. (Ein Feature ist solange atomar, solange niemanden zwei Merkmale in diesem Feature einfallen, welche von der Mehrheit anerkannt werden.)

Atomare Features in der Informatik zum aktuellen Zeitpunkt, sind beispielsweise :
Kopieren, Zeiger, Vererbung, Polymorphismus, Verschiebung, Lokalisierung, Container, Schablonen, Timing, Responsbility und mehr. (Bitte in den Kommentaren erweitern.)

Das entspricht in der Programmierung :
Copyconstructor, Pointer, Inheritance, Adressen und Addressoperationen, class/structs, Templates/Generics, Multithreading/Concurrency und Handshakes, Visibility.

Das sind alles Features, die in c++ enthalten sind, jedoch nicht in c.
Wir erlangen durch diese Features in der höheren Programmiersprache somit mehrere zusätzliche Dimensionen.
Java kann dies auch, jedoch hat es bis auf den Gabagecollector nicht mehr zusätzliche Features. Es lohnt sich also nicht Java und C++ zu können, sondern nur den Unterschied zu wissen. (Pointer, Copy Paradigma, Gabagecollector.)
Es ist so, dass die Sprache C, z.B. das Feature Vererbung nicht kann. Dennoch ist die Sprache touringvollständig. D.h. es ist möglich das gleiche Programm in C, wie auch C++ zu schreiben. Jedoch in einer geringeren Dimension und somit nicht so kreativ und vielfältig. Modellierung, soweit dies bedeutet Eigenschaften der Gegebenheiten zu formulieren, ist in C schwerer, da wir weniger abstrahierende Dimensionen haben.

In der Informatik gibt es nun zusätzlich sogenannte Domain Specific Languages (DSL). Es werden dabei Sprachen verwendet, welche die Business Logik abdecken. Sie beziehen sich beispielsweise auf den Bereich des Bankings. Konkret: Ein Banker kann damit Zahlungen spezifizieren oder Gegebenheiten des broking modellieren. Z.B. kann er sagen: verkaufe Aktie, wenn der Wert niedriger ist als andere Aktie.

Brauchen wir diese?
Ja, denn sie erhöhen die Dimensionen. Und wenn die Dimensionen endlich sind, dann kommt man dem Ziel näher.
Domain spezifische Sprachen sind notwendig. Jedoch, sollten sie nicht zu ähnlich sein. Zusätzlich sollten sie ausschließlich atomare und unterschiedliche Features implementieren.
Zum Beispiel wären da: Ableitung, Integral, Korrelation/Faltung und auch Bewertungssysteme, Fuzzi Logik, Kooperation (friend classes) und Kooperationsstrategien und ihre Bestandteile (John Nash Equilibrium).

Tools :
Aktuell gibt es ein interessantes Tool, welches sich Embededer nennt.
Dieses ist, mit MSP (ein DSL Tool), zusammen ein Werkzeug, welches sich sehr gut zur Definition eigener DSL dient. Und was mittlerweile auch auf C++ aufbaut.
Daneben sind weitere Tools wie Spufax und Eclipse Xtext zu empfehlen.
Vielleicht lässt sich das automatic completion Tool Xtext auch mittlerweile mit Embededer kombinieren.

Wieviele DSLs brauchen wir?
Nur noch wenige, denn die Maschinen sind endlich.
Ideen und Dimensionen womöglich unendlich.

Disclaimer :
Die verwendeten Begriffe entsprechen nicht zu 100% der üblichen Verwendung.
Genaue Angaben/Referenzen können leider nicht hinzugefügt werden.
Rassistische Eindrücke sind nur aufgrund der Informatik zu verschulden.
Änderungen der eigenen Meinung sind unbeabsichtigt. Stand 2016. Ort München. Kostenlose Vervielfältigung ist erlaubt, unter hinzufügen dieses Reclaimer. Das gut unterliegt der Creative Common License 3.0, zu finden unter creative-common.org.
Autor Sebastian Böhmer.

Montag, 18. Januar 2016

Three Threads Streaming


Three Threads Stream


About

Many applications are performing an editing of their input. Especially in image processing. They all need to buffer their input, if they want to handle the processing. Especially, if you want to process the reading, modify and writing of data not in one thread. So, you need buffers between the threads.
Here it describes the problem and gives a solution in form of an implementation.
Afterwards this document discuss the timing problematic with too slow or too fast threads.
Below, you can add some comments about your opinion. Don't hesitate to ask some questions.

Problem

As in "about" described, we want to process data for reading, modifying and writing. Of course, we can use one single data address to process the reading, modifying and writing in one single thread. But now we want to do this with three different threads. One for reading, one for modifying and one for writing.
So you can say: lets use one data address for all three threads. To avoid a race condition (simultaneous writing and reading), we use a mutex, which we can lock.

The issue is, that when we use a mutex, it could be, that only the input thread is accessing the data, while the modify thread is every time again waiting on the lock. This happens, because when the modify thread is checking, if the mutex is free again, the input thread has lock the mutex again. In that way, the input thread is much more faster than the modifying thread. And in this way, we omit a lot of data to modify and write.


The modifying thread is called working thread further on. And the writing thread is called output thread in the implementation.

So it is not suitable to use a mutex here. Because, we have too fast access on the mutex. More detailed, the threads run in different speed, so it can be, that one thread is running twice as fast as the other. Or one thread is running at whole, while the other thread do nothing.
So at least we need two conditions: not_full and not_empty to indicate the different states of the cyclic buffer, if only one thread is running. This buffer and conditions are invented by batptiste-wicht[1].

The implementation

The buffer "BoundedBuffer"[1] is slightly modified. It is now a template based class.
We need two buffers. One to transfer the input data to working thread, called inputToWorkingBuffer, and one to transfer modified data to output thread called workingToOutputBuffer. There are two operations on that buffers. One for fetching the last data and one for depositing new data.
There are streams handling the fetching and depositing of the buffers. See the operators << and >> therefore. The code is also improved by r-value references. The r-value references permit the data to be moved into the buffer and moved from the buffer. So the copy process is reduced as much as possible. In the end, there are only one copy from input stream to buffer and one copy to output stream.

The BoundedBuffer




The main




There are three threads in the main declared: inputThread, workingThread and outputThread. With get(), we wait of finishing the threads in reverse order of creation. std::ref(buffer) is needed on calling threads, because the buffer should be changed outside of the threads.

If all works correctly, we get the output of only even numbers from 0 to ttt::inputMax.

Timing Issues

There are 2^3 timing issues. This is because, every thread can be too slow or too fast. Those, timing issues are handled by some tricks. For example, if the outputThread is too fast, we can repeat the last frame.

All tricks are:
  • If working is too slow or input too fast, overwrite old data in inputToWorkingBuffer.
  • If input is too slow or working too fast, repeat return of last data in inputToWorkingBuffe.
  • If working is too slow or output too fast, repeat display of last data.
  • If output is too slow or working too fast, overwrite old data in workingToOutputBuffer.

fetch() must be changed to:


And we have to change deposit() slightly. All correct code will be in the gitHub[2].

The front size_t needs to be changed to atomic, because it is used in fetch() and deposit().


Have a lot of fun, Sebastian

References


[1] http://baptiste-wicht.com/posts/2012/04/c11-concurrency-tutorial-advanced-locking-and-condition-variables.html
[2] https://github.com/SebastianBoehmer/example/tree/master/threeThreadsStream

Samstag, 28. März 2015

Why to use linked list more often than dynamic arrays

Hello together,

About


today, it is about an issue, which concerns every computer consultant, programmer or computer scientist.
This topic is discussed about 56 million times on google (search string "list vs vector"). We need a clear decision to program qualitative and efficient programs. It is late in time to clarify the misunderstanding. And, you get the information for free. Independent on your location. This information is important to everyone, independent if you are a chief or a student.

The question is: What is the preferred container for your data?

We enlighten two containers: the list and the dynamic array (also called vector).

List

A list is a set of nodes, which consists of the data and one pointer to the next node. Nodes can be everywhere in the memory.
To have a reference to the list, we have a pointer to start of the list.
With few effort, we can also have a pointer to end of the list. This end-pointer is state of the art and typically the case (e.g. in STL lists), so we assume this additional condition.
More about lists you can read in "Algorithm and Data Structures"[1] or in the internet[2]

Vector

A vector is a set of data. This set is continuously combined in the memory.
To have a reference to the vector we have a so called offset.
More about dynamic arrays (vectors) can be read in "Algorithm and Data Structures"[1] or in the internet[3].


 The court

Most people prefer vectors over list. This was my experience in my research. 
Additionally, People using vectors blame people using lists to use vectors.
We assume therefore, that vector is the claimant and list is the defender.
So, we start with the arguments of using a vector.

Arguments of people using vectors:
- random access
- less memory
- faster allocation of memory
- faster indexing technical and theoretical
- compactness / discriminative

Claim of vectors

Random Access
There is the argument, that vectors have random access to their underlying data. This means, with a simple calculation of offset+x*s you get the memory position of the x'th data with size of data s. So, you can access the memory randomly in time O(1).
They claim: A list have to iterate from start x'th times to the next node.
This take O(n) time (see [1] for explanation of O-Notation).

Less Memory
They argue, that a list have to allocate additional memory for their next pointers. Lists allocate n times the next pointer, with a pointer currently 4 bytes in memory.
So, a dynamic array would only allocate the necessary space, while list would allocate the necessary space plus the next pointers. This is more space than necessary.

Faster Allocation of Memory
They claim the list to allocate the memory every time of a next element, which is every time a request to the system for free memory space. They argue, the request would take time, because some memory is already allocated and some memory is not allowed to use. Therefore, the system have to use complicated algorithms to request the memory space. Vectors, on the other hand, allocate only once their whole data space.

Faster Indexing Technical and Theoretical
First of all the technical is faster for vectors. They only have to calculate the next address of an arbitrary element in the container. While lists are using the next pointer to get the address. Therefore, they have to fetch the memory for the next pointer, while an array have only one calculation.
The second is the theoretical disadvantage of a list. The list have to iterate from start to the x'th node to get the data. This takes O(n) time.


Compactness / Discriminative
Additionally, there is an argument that lists are not compact. The nodes are equally distributed over the memory. So, loading the data into a cache does not have the same effect like for dynamic arrays.
Further on, "compactnes matters" - is it called from a famous computer expert.
This argument ("matters") is a little bit complicated. As far as I understand, it means: if you have compact data, you are not jumping around every time.
I will add the argument "Discriminative". This means, an array is allocating a whole memory block, so the data is distinguished between blocks. If your input is now distinguished between blocks, it is more easy to discriminate for the computer than it would be if the data is equally distributed. Some algorithms, which try to predict, have that problem of discrimination. This is used for example in the area of pattern recognition.


Plea

The defence appeals to innocent.


Random Access
This is true. Arrays have a faster random access than lists.
When do you need it? The most time you process data sequential.
Of course, your sensor or user input have random values, but the input is processed sequential.
Only if you have the inputs, which are coordinates according to an element of data. This is for example the case, if you have user input from the screen. On the screen you have input by the mouse in the form of coordinates. According to the coordinates, there are underlying elements on the screen, which should be processed.
Lists deputy argue, this case is the only one. In all other cases it is better to use lists, because they are processed sequential.
Please use lists more often than dynamic arrays!


Less Memory
To be honest, arrays wast memory also. They allocate memory, which is not immediately used.
Therefore ,you have to understand the concept for dynamic arrays.
Vector argue: There are tricks to reduce this allocation problem by creating a list of vectors.
The plea calls objection - this is manipulative. In this case comparison between lists and vectors are not possible.
Lets go back to the description of dynamic arrays.
Dynamic arrays double the size of allocated data at growing. Growing happens when you insert a new element to a filled dynamic array. In this moment, the array is allocating twice the current size and copies the old data to the new memory space. The old space is deleted afterwards.
This will take time and space. The time you need is amortized O(1) (see Table of O-Notations in [2]) to append a new element at the back of the array (the so called push_back() function). The space you need is amortized 3/4 * n space. This means you waste 1/4 * n space. We assume that an array is filled step by step with push_back(). So the averaged space used by the array is 3/4 full and 1/4 empty.
The plea want to submit evidence:
This evidence describe the amount of memory wasted by the list.
A pointer has currently 4byte. This is allocated n times. Makes 4*n byte.
The plea argue: If you have a data size s, which is over 16 byte, the array would wast memory of 1/4 * n * s. This is minimal 4 * n byte of memory. This is at least waisting as much space as a list do, for a >= 16byte data element.
On a machine with 64bi, using two integers reaches the size of 16bytes. See therefore [4].
The plea appeals to innocent, because of really rare exceptions of data structs below 16 byte.
Vector is interrupting: For big data we use pointers to the data.
The plea counters: Then, the advantage of arrays are going lost, because you need additional memory fetching.
The plea appeals to innocent in this case, cause lack of evidence!
Please use lists for data-elements above 16 bytes!
Doubles have already 8 byte[5]!

Faster Allocation of Memory
The plea is defending to innocent, because memory allocation is issued by array and list equally.
The defence submits some evidence: We are discussing about dynamic memory allocation. And about the currently common method of using blocks to handle the memory.
Dynamic memory allocation means, memory allocation while run-time.
Compared with static memory allocation, while compile-time, this is not yet allocated when you start the program.
The currently common method to use blocks is used to help avoiding fragmentation. As far as I understand, fragmentation is a problem, when you want to insert a big data-element and found no continuous space for it. Instead you have many small free spaces. So, you would have enough memory, but because of fragmentation there is no space for the big data.
The plea argue, if all data would have the same size, fragmentation would not happen. The problem therefore is not the size per se, but the difference in size.
So, arrays and lists are both equally guilty.
The plea appeals: In case of the accused.
The court sad: Fragmentation is not relevant here.

The plea gives them right and goes back to the topic.
The claimant intersects: The problem of allocation is not the fragmentation, but the overhead by the repeated allocation by the list.
The plea argues, that disadvantage is only different from array allocation if you use big arrays. In case of big arrays, the system will allocate a new block according to the size of the array, which is bigger than a threshold. In case of small arrays, the system have to look into the current block also. In this case of small arrays, you have to allocate often small arrays for big input.
So, you are also investigating the overhead.
Because of equal concern, the plea appeals for innocent.
Please use lists more often!

Faster Indexing - Technical and Theoretical
Technical is the indexing on arrays a calculation, whereas the indexing on lists is a fetching.
The plea agrees: This is a difference.
The computational steps on a list are:
1. reading memory address of next pointer from the register R2
2. fetching data from memory to register R1
3. and fetching next pointer from memory to register R2

The computational steps on a vector are:
1. increasing the index in the register
2. adding the offset from the register
3. fetching data from memory

Point 1. of array is typically an improvement for arrays.
The true steps of array would be:
1. reading index from register R1
2. calculating index + 1
3. reading offset from register R2
4. calculating index + offset
5. fetching data from memory to register R3

The plea appeals to think about the advantage on pipe-lining for fewer computational steps, as for lists.
Lists have no calculations.
The plea appeals to think about the register size.
List need only two register and therefore the processor can handle more lists synchronously.
Please, use lists for mixing different input!


Compactness / Discriminative
The plea begs the court to drop the argument of compactness, because it's misunderstanding.
My own argument Discriminative will be dropped, because the input is generally not discriminative. If the input would be discriminative, we could easily predict, just depending on which input we got. You would say, if the sensor A gives a signal it is an elephant and if the sensor B gives the signal it is a rabbit.



Conclusion

None of the arguments of vectors have had an evidence to prefer vectors over lists. Also, the performance is not arguable better.

Dynamic arrays are not better than lists.
Lists are more related to Touring-Machines.
If memory matters, use lists. If speed matters use vectors.
The problem is currently, that the additional data (next pointer) in the list
is used in the processing, while the additional data in the array (reserved fields) is not used in the processing.
This means, if speed really matters, the array would be better. Even though, fetching is slower than calculation, and lists do one more fetching.
On the other hand, the additional data of the list is only 4 byte for each element. And it is more recommended to use lists for big data (>16 bytes). See argument "less memory" above.
This means, if memory matters, use lists.


Beside the argument of memory, random access takes into account.
Use vectors only if you have random access mapping to data.
For example a user input by mouse on the screen. The mouse coordinate can be used to directly find the underlying data. This is also the case for mapping. In this case a map, which is a special array, is the best choice.
In all other cases, please prefer lists over vectors.
Your first question should be: Is my underlying data bigger than 16 bytes, then I use a list.
Now you can argue, nearly every primitive data type is below 16 byte (on 32bit machines). So we can split the data type bigger than 16 byte in several arrays with primitive data types.
That is true, you can do this if you can program in that way.
Normally, it is like baking a cake. You need different ingredients like milk, wheat, eggs and butter. Now you are combining the ingredients and processing them in the oven. In the end you should get a cake.
I don't know how to bake a cake without mixing the ingredients together.
Perhaps it is possible to mix the ingredients together in the last moment. This would be very hard to program.


Other Argue

"One block allocation - if you don't have enough memory to provide a single block (but you have sufficient scattered memory blocks) to allocate the space for the array then you'll need to defragment and other similar stuff to first create a free block of that size. So you may like to term it as improper utilization of memory :-)"
[http://geekexplains.blogspot.de/2008/05/array-vs-linked-list-advantages-and.html]

[http://programmers.stackexchange.com/questions/185222/what-is-the-point-of-using-lists-over-vectors-in-c]


References


[1] Th. Ottmann, P. Widmayer. Algorithmen und Datenstrukturen. xvii+716 Seiten, 4. Auflage, Spektrum Akademischer Verlag, Heidelberg 2002
[2] http://en.wikipedia.org/wiki/Linked_list 2015
[3] http://en.wikipedia.org/wiki/Dynamic_array 2015
[4] http://en.wikipedia.org/wiki/Integer_%28computer_science%29
[5] http://en.wikipedia.org/wiki/Floating_point