1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
|
Calculation
-----------
There are two different datasets used for benchmarking obtained from the :mod:`contourpy.util` functions
:func:`~contourpy.util.data.simple` and :func:`~contourpy.util.data.random`. The former is the sum
of two gaussians that results in a small number of relatively short contours. The latter is random
data that results in a large number of small contours and a few large contours; this is an extreme
dataset designed to stress the contouring algorithms. Both have the option to generate masked data.
All of the results shown are for a single chunk with a problem size ``n`` (``== nx == ny``) of 1000.
As a guide to the complexity of the output, the unmasked datasets generate the following line
contours in the benchmarks
- ``simple``: 38 lines of about 36 thousand points.
- ``random``: 850 thousand lines of about 7.4 million points.
and the following filled contours
- ``simple``: 55 boundaries (39 outers and 16 holes) of about 76 thousand points.
- ``random``: 1.7 million boundaries (half each of outers and holes) of about 15 million points.
Contour lines
^^^^^^^^^^^^^
.. image:: ../_static/lines_simple_1000_light.svg
:class: only-light
.. image:: ../_static/lines_simple_1000_dark.svg
:class: only-dark
For the ``simple`` dataset above the performance of :ref:`serial` for contour lines is the same
regardless of :class:`~.LineType`. It is about the same as :ref:`mpl2005` and significantly faster
than :ref:`mpl2014` with a speedup of 1.8-1.9.
.. image:: ../_static/lines_random_1000_light.svg
:class: only-light
.. image:: ../_static/lines_random_1000_dark.svg
:class: only-dark
For the ``random`` dataset above the performance of :ref:`serial` varies significantly by
:class:`~.LineType`. For ``LineType.SeparateCode`` :ref:`serial` is 10-20% faster than
:ref:`mpl2005`, and is about the same as :ref:`mpl2014` if masked and 10% slower if not masked.
Other :class:`~.LineType` are faster. ``LineType.Separate`` has a speedup of about 1.4 compared to
``LineType.SeparateCode``; most of the difference here is the time taken to allocate the extra 850
thousand `NumPy`_ arrays (one per line) and a small amount is the time taken to calculate the
`Matplotlib`_ kind codes to put in them.
The chunked line types (``LineType.ChunkCombinedCode``, ``LineType.ChunkCombinedOffset`` and
``LineType.ChunkCombinedNan``) have similar timings with a speedup of 2.4-2.7 compared to
``LineType.SeparateCode``. The big difference here again is in array allocation, for a single chunk
these two ``LineType`` allocate just two large arrays whereas ``LineType.SeparateCode`` allocates
1.7 million `NumPy`_ arrays, i.e. two per each line returned.
Filled contours
^^^^^^^^^^^^^^^
.. image:: ../_static/filled_simple_1000_light.svg
:class: only-light
.. image:: ../_static/filled_simple_1000_dark.svg
:class: only-dark
For the ``simple`` dataset above the performance of :ref:`serial` for filled contours is the same
regardless of :class:`~.FillType`. It is about the same as :ref:`mpl2005` and significantly
faster than :ref:`mpl2014` with a speedup of 1.9-2.0.
.. image:: ../_static/filled_random_1000_light.svg
:class: only-light
.. image:: ../_static/filled_random_1000_dark.svg
:class: only-dark
For the ``random`` dataset above the performance of :ref:`serial` varies significantly by :class:`~.FillType`.
For ``FillType.OuterCode`` it is faster than :ref:`mpl2014` with a speedup of 1.5-1.7. It is also
faster than :ref:`mpl2005` but only the ``corner_mask=False`` option is shown in full as the unmasked
benchmark here is off the scale at 11.7 seconds. The :ref:`mpl2005` algorithm calculates points for
outer and hole boundaries in an interleaved format which need to be reordered, and this approach
scales badly for a large outer boundary containing many holes as occurs here for unmasked ``z``.
Other :class:`~.FillType` are faster, although ``FillType.OuterOffset`` is only marginally so as it
creates the same number of `NumPy`_ arrays as ``FillType.OuterCode`` but the arrays are shorter.
The other four :class:`~.FillType` can be grouped in pairs: ``FillType.ChunkCombinedCodeOffset`` and
``FillType.ChunkCombinedOffsetOffset`` have a speedup of 1.8-2.0 compared to
``FillType.OuterCode``; whereas ``FillType.ChunkCombinedCode`` and
``FillType.ChunkCombinedOffset`` are marginally faster with a speedup of 1.9-2.1. The speed
improvement has the usual explanation that they only allocate a small number of arrays whereas
``FillType.OuterCode`` allocates 1.7 million arrays. ``FillType.ChunkCombinedCode`` and
``FillType.ChunkCombinedOffset`` are slightly faster than the other two because they do not
determine the relationships between outer boundaries and their holes, they treat all boundaries the
same.
|