Permutations

The purpose of this page is to analyse the performance of our algorithms, especially with regard to the differences between the array and the linked list version.

In all cases, the programs were compiled and executed on an Intel 166mhz pentium processor with 32MB RAM, running Linux kernel 2.2.5-15 with the EGCS compiler version 2.95.2 with the -O3 optimisation flag set.

Because outputting data to the screen is actually quite resource intensive, two sets of performance data are provided, one where each permutation is output as it is calculated, and one where no permutations are ever output.

Executable size

VersionSize (KB)
Array version14.256
Linked list14.831

The array version is slightly smaller in executable size, which is not surprising given how much more concise the source code is.

Performance (with output)

InvocationPermutationsArray (secs)Linked list (secs)
./perm 11--
./perm 22--
./perm 36--
./perm 424--
./perm 5120--
./perm 67200.050.06
./perm 75,0400.360.45
./perm 840,3202.973.68
./perm 9362,88027.6434.36

The linked list version is slower in each case, but the slowness of the output routines are masking the real difference in performance.

Performance (no output)

InvocationPermutationsArray (secs)Linked list (secs)A : L
./perm 11---
./perm 22---
./perm 36---
./perm 424---
./perm 5120---
./perm 6720---
./perm 75,0400.0150.0818.75%
./perm 840,3200.120.6418.75%
./perm 9362,8801.065.8718.06%
./perm 103,628,80010.6159.2717.90%
./perm 1139,916,800116.61661.7317.62%

Here we can see that the array version is much faster, by over five times. This may be surprising, given that the main operations are inserting and removing data items, operations that linked lists are generally considered to be more efficient with (as the rest of the list does not have to be shifted backwards or forwards one by one).

We can explain this phenomena by noting that the lists we are using are actually quite small, no more than 11 elements in the tests above. It therefore seems that at these levels, the performance lost by having to shift array elements when inserting and deleting are more than made up for by the reduced number of processor steps in the rest of the array algorithm, including the fact that we don't have to continually ask the operating system for memory.

We may postulate, therefore, that at higher number of items, the linked list version will become relatively quicker. This is supported by the above data, which shows that despite the array version being five times faster, as we increase the number of items its performance advantage becomes gradually smaller.

This example shows that optimisation involves choosing algorithms with careful regard to the type and amount of processing we are going to be doing, and that optimisation of our algorithm is usually (though not always) far more important than micro-optimisation of the "is ++count faster than count++?" variety.