{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "In [previous](https://the-fonz.gitlab.io/posts/array-databases/) [posts](https://the-fonz.gitlab.io/posts/interpolation/) we explored how to work efficiently with [xarray](xarray.pydata.org/) and geospatial meteorological data, and while it would be possible to throw in extra adjectives to make that sound even more impressive, let's focus on the storage of this data.\n", "\n", "\n", "\n", "[Zarr](xarray.pydata.org/) is a relatively new storage format for multidimensional array data that puts every \"array chunk\" in a separate file/blob, allowing many different encoding/compression schemes within that blob while giving up random reads, which is fine as for (cloud) blob storage the latency overhead of getting a blob is relatively high, but bandwidth high as well so better just download the whole blob in one go. For google's cloud storage, these prices can be expected:\n", "\n", "| Storage type | Price [$/GB/month] | Retrieval cost [GB] |\n", "|---|---|---|\n", "| [Standard](https://cloud.google.com/storage/docs/storage-classes#standard) | .02 | 0 |\n", "| [Nearline](https://cloud.google.com/storage/docs/storage-classes#nearline) | .01 | 0.01 |\n", "| [Coldline](https://cloud.google.com/storage/docs/storage-classes#coldline) | .004 | 0.02 |\n", "| [Archive](https://cloud.google.com/storage/docs/storage-classes#archive) | .0012 | 0.05 |\n", "\n", "Please note that these prices are approximate and may vary by region and may become cheaper over time (I remember standard storage costing .026 \\\\$/GB/month not too long ago, can still see that price in some examples). Minimum storage duration is 30 days for nearline and 90 days for coldline, and there is a small cost for operations (delete/move etc) but that is usually negligible. Availability SLAs are also best for standard storage and go down a bit for the cold storage classes. Also, I assume the data is used mostly in gcloud datacenters, as egress cost of ~.10 \\\\$/GB will quickly eclipse any storage cost.\n", "\n", "From the table above, it's easy to deduct that nearline storage is cheaper than standard when downloaded less than once a month, while coldline is cheaper when downloaded at most once every 1.5 months, and archive at most once every 3 months. It can be a nice trick to set a lifecycle policy on a cloud storage bucket that moves objects to nearline after 1 month.\n", "\n", "This compares to about .05 \\\\$/GB/month for block storage on HDDs, up to .17 \\\\$/GB/month for block storage on SSDs, so blob storage is at least 2.5x cheaper. Also, it's difficult to mount block storage for concurrent reading/writing as one would need compute on top of the storage that runs something like NFS which allows connection over the network. This shows why it's so important to have good support for blob storage in file formats for storing huge amounts of numeric array data.\n", "\n", "I want to know what the best preprocessing steps (quantization?) are, what the compresson algorithm is with the best tradeoff of speed/compression, and if byte shuffling yields significant benefits.\n", "\n", "## The data\n", "We use ERA5 again as it's a representative set of meteo data, but this time downloaded from the awesome Pangeo cloud storage buckets. Make sure you use a gcloud account with billing enabled, as it's requester-pays on these buckets. See [the instructions here](https://catalog.pangeo.io/browse/master/atmosphere/era5_hourly_reanalysis_single_levels_sa/)." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "!pip install -q intake intake-xarray gcsfs" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import os\n", "import tempfile\n", "from datetime import datetime\n", "from time import time\n", "from pathlib import Path\n", "\n", "import numpy as np\n", "from intake import open_catalog\n", "from itertools import permutations\n", "import matplotlib.pyplot as plt\n", "from numcodecs import blosc\n", "from zarr.codecs import Blosc\n", "# Use nice seaborn mpl theme\n", "import seaborn as sns\n", "sns.set_theme()\n", "\n", "# Make fair comparisons with compression algorithms later (some use multiple threads by default)\n", "blosc.set_nthreads(1);" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.Dataset>\n",
       "Dimensions:    (latitude: 721, longitude: 1440, time: 350640)\n",
       "Coordinates:\n",
       "  * latitude   (latitude) float32 90.0 89.75 89.5 89.25 ... -89.5 -89.75 -90.0\n",
       "  * longitude  (longitude) float32 0.0 0.25 0.5 0.75 ... 359.25 359.5 359.75\n",
       "  * time       (time) datetime64[ns] 1979-01-01 ... 2018-12-31T23:00:00\n",
       "Data variables:\n",
       "    asn        (time, latitude, longitude) float32 dask.array<chunksize=(31, 721, 1440), meta=np.ndarray>\n",
       "    d2m        (time, latitude, longitude) float32 dask.array<chunksize=(31, 721, 1440), meta=np.ndarray>\n",
       "    e          (time, latitude, longitude) float32 dask.array<chunksize=(31, 721, 1440), meta=np.ndarray>\n",
       "    mn2t       (time, latitude, longitude) float32 dask.array<chunksize=(31, 721, 1440), meta=np.ndarray>\n",
       "    mx2t       (time, latitude, longitude) float32 dask.array<chunksize=(31, 721, 1440), meta=np.ndarray>\n",
       "    ptype      (time, latitude, longitude) float32 dask.array<chunksize=(31, 721, 1440), meta=np.ndarray>\n",
       "    ro         (time, latitude, longitude) float32 dask.array<chunksize=(31, 721, 1440), meta=np.ndarray>\n",
       "    sd         (time, latitude, longitude) float32 dask.array<chunksize=(31, 721, 1440), meta=np.ndarray>\n",
       "    sro        (time, latitude, longitude) float32 dask.array<chunksize=(31, 721, 1440), meta=np.ndarray>\n",
       "    ssr        (time, latitude, longitude) float32 dask.array<chunksize=(31, 721, 1440), meta=np.ndarray>\n",
       "    t2m        (time, latitude, longitude) float32 dask.array<chunksize=(31, 721, 1440), meta=np.ndarray>\n",
       "    tcc        (time, latitude, longitude) float32 dask.array<chunksize=(31, 721, 1440), meta=np.ndarray>\n",
       "    tcrw       (time, latitude, longitude) float32 dask.array<chunksize=(31, 721, 1440), meta=np.ndarray>\n",
       "    tp         (time, latitude, longitude) float32 dask.array<chunksize=(31, 721, 1440), meta=np.ndarray>\n",
       "    tsn        (time, latitude, longitude) float32 dask.array<chunksize=(31, 721, 1440), meta=np.ndarray>\n",
       "    u10        (time, latitude, longitude) float32 dask.array<chunksize=(31, 721, 1440), meta=np.ndarray>\n",
       "    v10        (time, latitude, longitude) float32 dask.array<chunksize=(31, 721, 1440), meta=np.ndarray>\n",
       "Attributes:\n",
       "    Conventions:  CF-1.6\n",
       "    history:      2019-09-20 05:15:01 GMT by grib_to_netcdf-2.10.0: /opt/ecmw...
" ], "text/plain": [ "\n", "Dimensions: (latitude: 721, longitude: 1440, time: 350640)\n", "Coordinates:\n", " * latitude (latitude) float32 90.0 89.75 89.5 89.25 ... -89.5 -89.75 -90.0\n", " * longitude (longitude) float32 0.0 0.25 0.5 0.75 ... 359.25 359.5 359.75\n", " * time (time) datetime64[ns] 1979-01-01 ... 2018-12-31T23:00:00\n", "Data variables:\n", " asn (time, latitude, longitude) float32 dask.array\n", " d2m (time, latitude, longitude) float32 dask.array\n", " e (time, latitude, longitude) float32 dask.array\n", " mn2t (time, latitude, longitude) float32 dask.array\n", " mx2t (time, latitude, longitude) float32 dask.array\n", " ptype (time, latitude, longitude) float32 dask.array\n", " ro (time, latitude, longitude) float32 dask.array\n", " sd (time, latitude, longitude) float32 dask.array\n", " sro (time, latitude, longitude) float32 dask.array\n", " ssr (time, latitude, longitude) float32 dask.array\n", " t2m (time, latitude, longitude) float32 dask.array\n", " tcc (time, latitude, longitude) float32 dask.array\n", " tcrw (time, latitude, longitude) float32 dask.array\n", " tp (time, latitude, longitude) float32 dask.array\n", " tsn (time, latitude, longitude) float32 dask.array\n", " u10 (time, latitude, longitude) float32 dask.array\n", " v10 (time, latitude, longitude) float32 dask.array\n", "Attributes:\n", " Conventions: CF-1.6\n", " history: 2019-09-20 05:15:01 GMT by grib_to_netcdf-2.10.0: /opt/ecmw..." ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# See instructions at https://catalog.pangeo.io/browse/master/atmosphere/era5_hourly_reanalysis_single_levels_sa/\n", "cat = open_catalog(\"https://raw.githubusercontent.com/pangeo-data/pangeo-datastore/master/intake-catalogs/atmosphere.yaml\")\n", "ds = cat[\"era5_hourly_reanalysis_single_levels_sa\"].to_dask()\n", "ds" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Array Chunk
Bytes 1.46 TB 128.74 MB
Shape (350640, 721, 1440) (31, 721, 1440)
Count 11312 Tasks 11311 Chunks
Type float32 numpy.ndarray
\n", "
\n", "\n", "\n", " \n", " \n", " \n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n", " \n", " \n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "\n", " \n", " \n", " \n", "\n", " \n", " \n", "\n", " \n", " \n", " \n", "\n", " \n", " \n", " \n", "\n", " \n", " \n", "\n", " \n", " 1440\n", " 721\n", " 350640\n", "\n", "
" ], "text/plain": [ "dask.array" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ds.t2m.data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we'll load a subset of this data into memory. As we can see above, the dataset is only chunked in time, per 31 timesteps. We'll slice to just one chunk to be able to download it quickly." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Array Chunk
Bytes 128.74 MB 128.74 MB
Shape (31, 721, 1440) (31, 721, 1440)
Count 11313 Tasks 1 Chunks
Type float32 numpy.ndarray
\n", "
\n", "\n", "\n", " \n", " \n", " \n", "\n", " \n", " \n", " \n", "\n", " \n", " \n", "\n", " \n", " \n", " \n", "\n", " \n", " \n", " \n", "\n", " \n", " \n", "\n", " \n", " \n", " \n", "\n", " \n", " \n", " \n", "\n", " \n", " \n", "\n", " \n", " 1440\n", " 721\n", " 31\n", "\n", "
" ], "text/plain": [ "dask.array" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ds2 = ds.isel(time=slice(0, 31))\n", "ds2.t2m.data" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 24.9 s, sys: 13.1 s, total: 38 s\n", "Wall time: 1min 22s\n" ] }, { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.Dataset>\n",
       "Dimensions:    (latitude: 721, longitude: 1440, time: 31)\n",
       "Coordinates:\n",
       "  * latitude   (latitude) float32 90.0 89.75 89.5 89.25 ... -89.5 -89.75 -90.0\n",
       "  * longitude  (longitude) float32 0.0 0.25 0.5 0.75 ... 359.25 359.5 359.75\n",
       "  * time       (time) datetime64[ns] 1979-01-01 ... 1979-01-02T06:00:00\n",
       "Data variables:\n",
       "    asn        (time, latitude, longitude) float32 0.88000053 ... 0.850001\n",
       "    d2m        (time, latitude, longitude) float32 240.97255 ... 244.83789\n",
       "    e          (time, latitude, longitude) float32 nan nan ... 4.9493974e-07\n",
       "    mn2t       (time, latitude, longitude) float32 nan nan ... 248.4101 248.4101\n",
       "    mx2t       (time, latitude, longitude) float32 nan nan ... 248.46516\n",
       "    ptype      (time, latitude, longitude) float32 nan nan nan ... 0.0 0.0 0.0\n",
       "    ro         (time, latitude, longitude) float32 nan nan nan ... 0.0 0.0 0.0\n",
       "    sd         (time, latitude, longitude) float32 0.0 0.0 0.0 ... 10.0 10.0\n",
       "    sro        (time, latitude, longitude) float32 nan nan nan ... 0.0 0.0 0.0\n",
       "    ssr        (time, latitude, longitude) float32 nan nan ... 268708.75\n",
       "    t2m        (time, latitude, longitude) float32 244.07776 ... 248.47702\n",
       "    tcc        (time, latitude, longitude) float32 1.0 1.0 1.0 ... 0.0 0.0 0.0\n",
       "    tcrw       (time, latitude, longitude) float32 0.0 0.0 0.0 ... 0.0 0.0 0.0\n",
       "    tp         (time, latitude, longitude) float32 nan nan nan ... 0.0 0.0 0.0\n",
       "    tsn        (time, latitude, longitude) float32 245.32692 ... 246.29123\n",
       "    u10        (time, latitude, longitude) float32 0.01948136 ... 0.52920276\n",
       "    v10        (time, latitude, longitude) float32 -0.024540722 ... 0.22564238\n",
       "Attributes:\n",
       "    Conventions:  CF-1.6\n",
       "    history:      2019-09-20 05:15:01 GMT by grib_to_netcdf-2.10.0: /opt/ecmw...
" ], "text/plain": [ "\n", "Dimensions: (latitude: 721, longitude: 1440, time: 31)\n", "Coordinates:\n", " * latitude (latitude) float32 90.0 89.75 89.5 89.25 ... -89.5 -89.75 -90.0\n", " * longitude (longitude) float32 0.0 0.25 0.5 0.75 ... 359.25 359.5 359.75\n", " * time (time) datetime64[ns] 1979-01-01 ... 1979-01-02T06:00:00\n", "Data variables:\n", " asn (time, latitude, longitude) float32 0.88000053 ... 0.850001\n", " d2m (time, latitude, longitude) float32 240.97255 ... 244.83789\n", " e (time, latitude, longitude) float32 nan nan ... 4.9493974e-07\n", " mn2t (time, latitude, longitude) float32 nan nan ... 248.4101 248.4101\n", " mx2t (time, latitude, longitude) float32 nan nan ... 248.46516\n", " ptype (time, latitude, longitude) float32 nan nan nan ... 0.0 0.0 0.0\n", " ro (time, latitude, longitude) float32 nan nan nan ... 0.0 0.0 0.0\n", " sd (time, latitude, longitude) float32 0.0 0.0 0.0 ... 10.0 10.0\n", " sro (time, latitude, longitude) float32 nan nan nan ... 0.0 0.0 0.0\n", " ssr (time, latitude, longitude) float32 nan nan ... 268708.75\n", " t2m (time, latitude, longitude) float32 244.07776 ... 248.47702\n", " tcc (time, latitude, longitude) float32 1.0 1.0 1.0 ... 0.0 0.0 0.0\n", " tcrw (time, latitude, longitude) float32 0.0 0.0 0.0 ... 0.0 0.0 0.0\n", " tp (time, latitude, longitude) float32 nan nan nan ... 0.0 0.0 0.0\n", " tsn (time, latitude, longitude) float32 245.32692 ... 246.29123\n", " u10 (time, latitude, longitude) float32 0.01948136 ... 0.52920276\n", " v10 (time, latitude, longitude) float32 -0.024540722 ... 0.22564238\n", "Attributes:\n", " Conventions: CF-1.6\n", " history: 2019-09-20 05:15:01 GMT by grib_to_netcdf-2.10.0: /opt/ecmw..." ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%time\n", "ds2.load()" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'chunks': (31, 721, 1440),\n", " 'compressor': Blosc(cname='lz4', clevel=5, shuffle=SHUFFLE, blocksize=0),\n", " 'filters': None,\n", " 'missing_value': -32767.0,\n", " '_FillValue': -32767,\n", " 'scale_factor': 0.0016946343655403098,\n", " 'add_offset': 265.9707255587938,\n", " 'dtype': dtype('int16')}" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ds2.t2m.encoding" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Establishing baselines\n", "\n", "We see above that there is already some quantization used by setting a scale factor and offset and converting from float32 to int16. (This is xarray functionality, not zarr/numcodecs filters.) In addition, the Blosc metacompressor is used, which can do byte-shuffling. This is very efficient for numerical data, as all first bytes are first compressed, then all second bytes etc., and these are much more alike than the subsequent bytes in an int or float. Let's see what that results in, in terms of disk usage." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Total size uncompressed float32 2163.606Mi\n", "Total size compressed float32 816.666Mi\n", "Total size compressed float32 noshuffle 1066.917Mi\n", "Total size compressed (original encoding) 468.758Mi\n" ] } ], "source": [ "# Track experiments for plotting later\n", "results = []\n", "\n", "def dirsize_mb(p: str):\n", " return sum(f.stat().st_size for f in Path(p).glob('**/*'))/2**20\n", "\n", "def experiment(name, encoding, transpose_order=None, record=True): \n", " with tempfile.TemporaryDirectory() as tmpdir:\n", " t0 = time()\n", " if transpose_order:\n", " ds2.transpose(*transpose_order).to_zarr(tmpdir, encoding=encoding)\n", " else:\n", " ds2.to_zarr(tmpdir, encoding=encoding)\n", " t = time() - t0\n", " size = dirsize_mb(tmpdir)\n", " print(f\"Total size {name} {size:.3f}Mi\")\n", " if record:\n", " results.append((name, size, t))\n", "\n", "experiment(\"uncompressed float32\", {k: {\"compressor\": None} for k in ds.data_vars.keys()})\n", "experiment(\"compressed float32\", {k: {\n", " \"compressor\": Blosc(cname='lz4', clevel=5, shuffle=Blosc.SHUFFLE, blocksize=0),\n", " \"filters\": None,\n", " \"dtype\": np.float32\n", "} for k in ds.data_vars.keys()})\n", "experiment(\"compressed float32 noshuffle\", {k: {\n", " \"compressor\": Blosc(cname='lz4', clevel=5, shuffle=Blosc.NOSHUFFLE, blocksize=0),\n", " \"filters\": None,\n", " \"dtype\": np.float32\n", "} for k in ds.data_vars.keys()})\n", "experiment(\"compressed (original encoding)\", None)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "All right, our first data points! The total size is 2.2GB without any compression, .8GB with lossless compression, and finally we see that the efficient (lossy) quantization applied by Pangeo results in a compressed size of just ~.5GB. (That's why the download was faster than expected.)\n", "\n", "Let's see what the compression ratio of different vars is." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAtQAAAELCAYAAAD5rRGXAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAAAuRElEQVR4nO3deVSU9eLH8c8MCLgRQai4lGaJqFfR1PKnZKmluaFtmj+zG6VZlmbqdcctc99zzzYrLU1R1LJFr9clTHMlvVb+yCzFBaRAWYR5fn9wnCOJA/LMDIO+X+d4DjPzzPP9zIaf+fIsFsMwDAEAAAAoEmtxBwAAAABKMgo1AAAAYAKFGgAAADCBQg0AAACYQKEGAAAATKBQAwAAACZQqAHAg4WGhurEiRM3dJ/169crKirKRYmKz6JFizRy5MjijgEA16BQA0ARNGzY0P6vdu3aql+/vv3y+vXr873P7t279eCDD7o8W+fOnfXuu++6bP3PPfecQkNDlZ2dnef6Dz74QK1atVJ4eLgee+wxJSQkSJIMw9DChQv10EMPqVGjRho4cKDS0tLs93v22WcVGhqq//73v3nW169fP4WGhmr37t2SpL59+2rixIkue1wAUFQUagAogv3799v/Va5cWYsWLbJf7ty5c3HHc5n169dfU6QladWqVVq9erWWLFmi/fv3a/Hixbr99tslSTExMVq3bp1WrFih7du3KyMjQxMmTMhz/+rVqysmJsZ++cKFCzpw4IACAwNd+ngAwBko1ADgRFlZWZo4caJatGihFi1aaOLEicrKytKlS5fUu3dvnT171j6TfebMGR06dEjdunVT48aN1aJFC40fP15ZWVmFGmvNmjVq3bq1GjZsqFatWtlnxtesWaNnnnlGkrR06dI8s+l169bVsGHDJEmpqakaMWKEWrRooYiICM2aNUs5OTnXHS81NVXz58/XkCFD8lxvs9n09ttva8SIEbrnnntksVh05513KiAgQJK0detWPfnkkwoJCVHZsmXVu3dvbdq0Senp6fZ1dOrUSZs2bbKPv3HjRrVp00alSpWyLzNv3jwNHjy4UM8NALgThRoAnGjhwoU6ePCg1q1bp/Xr1+vw4cNasGCBypQpo6VLl6pChQr2meyKFSvKarVq+PDhiouL08qVK/Xdd9/pk08+KXCcS5cu6c0339TSpUu1f/9+rVy5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8KD8/Py0YMECBQcHFznTuHHjJOU+RqvVquXLl6t06dKScmfQDcNQSkqKKlWqpGeffVZ169bVoUOH9Mcff6hXr16qWLGiPvroI509e1ZDhgzRY489VuQsBWVbsGCB3n77bcXHx8tisahx48aKjo5WVlaWZs2ape3bt8tqtapatWou+SvH3/N07NhRa9askY+Pj2w2m2bPnq2aNWuqVatWioyM1K5du3Tu3DlFRUWpZ8+epsYODQ3V66+/rm+++UYpKSl68803tWvXLm3fvl3Z2dmaM2eOatasqd27d+utt95SgwYNtH//flksFs2aNUs1a9ZUrVq17Ovz8fFRnTp1dOrUKV24cEFz585VWlqaIiMj1aRJE40aNcopedatW6ePPvpIn3zyiby8vBQVFaW2bdvqmWee0cMPP2xfX3h4uBITE2Wz2bR48WKdPXtW/fv3l6+vr2bMmKF77rnH1PP3dwcPHtT06dPtf5nq37+/HnroIaeOkZ/09HQNHTpUv/zyi7y9vVWjRg0NGDBAw4cPV3p6umw2m7p27aoXXnhB8+bN088//6y0tDSdOnVKn376qW677TaXZfv7+7tKlSoKDAzUL7/8ogsXLqhJkyaKjo6Wj4+Py8a83mf8789F//79FRMToyVLligpKUnNmzfXrFmz9Nhjj2np0qVKTU3VG2+8YTrfoEGDlJCQoMuXL+vOO+/UW2+9paSkpOu+XgkJCUpNTdXJkyd15513as6cOfbfp86W33tpzpw5mjVrljZt2iR/f381bdrUKWOFhoaqX79++vbbb5WRkaE33nhDbdu2veb1W7JkiZ544gl9++238vX1lST17dtXHTp0UMOGDfXEE0+oa9eu2rlzpyRpzJgx9v9nt23bpoULFyorK0ulSpXS8OHDFR4e7pTsr776qv79738rIiJCPXv21JgxY/Tbb79Jkl544QV16dLF9DiO5Pda9ejRQ2+++abq1aunI0eO6PXXX1dQUJAmTpyoS5cuqUyZMho5cqTq16/v0mxOV9yN/mbyxx9/GM2bN7d/E/zwww/zzO7mNxP20ksvGZs2bbJf3rhxo/HSSy85Jc/JkyeNpk2bXveyYVz7DfvLL780evfunWeZ+vXrGxcuXChyjnPnzhlNmzY1jh8/bhiGYSxZsiTfmfHnnnvO+OCDD+xZa9WqZWzdutUwDMNYunSpcd999xlHjhwxDMMwxowZY8ycObPIma643gzDmjVrjC5dutgv9+zZ0xgwYICRk5NjJCYmGvXr17ePf/DgQSMiIsJ0FkfZhg0bZowfP97IyckxDMMwkpKSDMMwjHnz5hn9+vUzMjMz81zvClfnadSokXHmzBnDMHJnfK/M7D/88MPG5MmTDcPIfQ3Dw8NNz+DUqlXL+OijjwzDMIxNmzYZ4eHhxpYtWwzDyH0vDRo0yDCM3BmpOnXqGD/++KNhGIaxYMEC44033rhmfefPnzeaN29uX+5GZ6gLm8cwDGP48OHGpEmTjHnz5hn9+/fPd31XXsMrXDlD/eeffxqRkZH21+7MmTNGRESE8eeff7pkvKt99dVXRlRUlP1ySkqKMWHCBGPRokV5rjMMw5g7d67RsmVLl76f/+7q9/fQoUONjh07Gmlpacbly5eN559/3li+fLlLx7zeZ/zvz8WlS5eMpk2bGllZWUZsbKzRrVs3Y/To0YZhGEZUVJSxa9cup2S7+rmfOXOmMW3aNIev1yOPPGL8+eefhs1mM55//nnj008/dUqO/OT3Xvr222/tr1l2drbx0ksvOWWGulatWsa8efMMwzCM48ePG02bNjXOnz9vv+3q32+vv/66sWbNGsMwcn//NW/e3MjMzLT/f3blr2JxcXFGRESEkZmZaZw4ccJ4+umnjdTUVMMwDOOnn34yWrZsaTr3lXyLFy+2Xx4wYIAxa9YswzByP/vNmzd3+V/D8nut4uLijNq1axv79u0zDCP3/5CWLVva37s7d+40WrZsaf9/raRgG2onqly5su655x5t27ZNkrR27VqXb8NVEhw8eFB16tSxn/2yW7du1ywzYcIElSlTJs9sZpkyZewzZ3Xr1lWlSpUUFhZmv3zlW7azff/995ozZ45mzJiR5/p27drJarWqYsWKCggIUJs2bexZzpw5o8zMTJfkkaStW7fqhRdekNWa+5ENDAy0X//cc8/ZZ86uXO9qDzzwgIYNG6bly5frzJkzeWai2rdvL0mqWrWq/P39lZiYaHq8K7P/devWlST7DG+9evXyvA9q1KihOnXqSMqd+T158mSe9aSlpenll19WVFSUfTlX5omOjtZ//vMfrV+/XhMnTrxmPRs3blRsbKzGjh1b5Cw3Yv/+/fr999/Vu3dvRUZGqnfv3rJYLDpx4oTLx65du7aOHz+ucePG6YsvvpCPj4+aNGmiVatWafbs2fruu+/k7+9vX/7BBx902/s5P+3bt1fZsmXl7e2tLl26KC4uzqXjXe8zLuV9LkqXLq17771XBw8e1K5du/TKK69o//79ysrK0uHDh9WoUSOn5Fm3bp0ef/xxderUSRs2bNDRo0cdvl4tWrSQv7+/LBaL6tev77Lfz1L+76Xdu3fbXzMvLy89+eSTThvvqaeekiTdfffdqlOnjg4cOJDvcs8++6w++eQTSdLKlSv1xBNP2H83lypVSp07d5Yk3X///fLz89P//d//afv27frtt9/0v//7v4qMjNTgwYOVnZ2t8+fPOyV7165d7T9/99136t69uySpQoUKatmypf0v2K6S32slSXfddZcaNmwoSUpISFCpUqXsfzn/n//5H5UqVUoJCQkuzeZsFGon69q1q2JiYnTs2DGlpqba/6RzPSEhITp16pT98unTpxUSEuKULN7e3vYdryQVqvD9PU9ycrKsVqsCAgKckik/U6ZM0YkTJzR79mz7fyaS8vx51Wq15rns5eWlnJwcp2fZv3+/hgwZovnz59u/AFxx5c94V8a/ctnLy0uSlJ2d7fQ8nurtt9/W66+/rvT0dPXq1cv+JVK69nlyxut0ZZ1/fx9YrdY8z7uj29LT09W3b181b95cUVFRbslz7tw5Xbp0SZcvX1ZaWlqedXz99deaNWuWli1bpjvuuMNUnsIyDEOhoaFat26d/d+2bdv0j3/8w+VjV6tWTRs2bFDz5s313XffKTIyUg899JA+/vhj3XnnnVq6dKmGDBliX75s2bIuz1RS/P25eOCBBxQXF6eDBw/qgQceUFBQkDZu3KjatWvn+fwV1d69e7VixQq98847io2N1euvv66srCy1bdv2uq+XKz7315Pfe8kTNGrUSDk5Ofrhhx+0du1ae3ktSERERJ7P5I4dO5z2O6FMmTJOWU9R5fdaZWZmFnsuV6BQO9mjjz6qPXv26L333lPXrl1lsVgcLt+uXTvFxMQoIyNDGRkZiomJcdq2uHfccYcuX75sn33asGFDgfepV6+eMjIytHfvXkm537LbtWtnKkd4eLiOHDmiX3/9VZK0atUq+20zZ85UfHy85s+f79TtEwurbNmy9qJz6NAhDRw4UHPnzrXPPBanq7M9/PDDWrZsmf0L0pWjoTz88MP64IMP7Huau/IoKVfyZGdn6+TJk6pfv7769Omj5s2b6+jRoy4b1xkyMzPVt29fNWjQQAMGDMhzW7ly5ZSamur0MbOysjRw4EANGTJEr776qgYOHGgv21u3btWkSZO0bNkyVa1aNc/9ypYt65I8ktSwYUOdOHEiz2zroUOH8nzxdpXExER5eXmpTZs2Gj58uJKTk3Xo0CEFBwfr8ccfV79+/fIc7cTdrv68SdKXX36pS5cuKTs7W+vWrdMDDzzg0jGv9xnPzwMPPKA1a9aoUqVK8vHxUbNmzTRv3rzr7htzo/766y+VK1dOAQEBysrK0ueffy5JOnHihEe8Xvm9l8LCwvTFF1/o0qVLysnJsWd2hivr+vXXX3XkyBH79s1/f89IubPUb7zxhho2bJhncuzy5cuKjY2VlPuFJSMjQ3fffbeaN2+u7du36+eff7Yve+jQIadlv1qzZs302WefScr9sr9t2zaXvK+vlt9r9eeff+ZZpkaNGrp8+bL999J3332n7Oxs1ahRw6XZnI2dEp2sdOnSat26tdasWaNvv/1WUu4Odj169FBGRoYyMzP14IMP6rXXXtNTTz2l+++/X48++qg6dOggKXenRGftTOHt7a2RI0fq+eefV2BgYJ4dj1599VX7h7Zdu3aqVauWli1bJqvVqqlTp2rMmDHKzMxUlSpVNG3aNFM5goKCNGHCBPXt21d+fn72nRJPnjypxYsXq3r16vZv8lWrVnXboQMlKSoqSr169ZKfn5/S09OVkZGh6Oho++1Tp05VaGio2/JcL9vy5cv11ltvqWPHjvLy8lLTpk01atQo9enTRzNmzFCXLl1UqlQp3XXXXZo7d65L81itVnl75/7qsFgsCgkJ0aBBg1wyprOsXr1a33//vVJSUrRjxw5Jue/7l19+Wc2aNdO7776rzp07259XZ5g2bZrCwsLsn+24uDjNnj1bgwcP1vDhw1WqVKk8h9F8//33dfvtt6tXr14aMWKE/Pz8nL5T4m233aYFCxZo2rRpeuutt3T58mVVq1ZNixYtKvDLv1nHjh2zb0Zls9nUp08f/fDDDxo7dqxKlSoli8Vi36G7OFz9eatSpYr+8Y9/KCoqSsnJyWratKmefvppl455vc94fho0aKALFy6oR48eknKL0syZM51WjiIiIrR+/Xq1bdtWt99+uxo3bqzDhw/riy++UGxsbLG/Xvm9l7p06aKEhARFRkbad0o8c+aMU8bLyclRly5dlJ6ervHjxysoKEjSta+fv7+/OnTooPHjx9tfmysCAgL03//+V++8846k3MkkHx8fVa9eXdOmTdPIkSOVkZGhy5cvq1GjRi7ZIW/UqFGKjo5Wp06dJEmDBw/Wvffe6/Rxrpbfa1WhQoU8y/j4+Gju3Ll5dkqcM2dOsUyymWEx3DE1AQBACTFs2DDVq1fP9BFqUPKFhoZq3759hd4Eae/evRo7dqxiY2PtX1L/fsQt3JyYoQYAADBpxIgR2rVrl6ZMmeLyv/jA8zBDDQAAAJjATokAAACACRRqAAAAwAQKNQAAAGAChRoAAAAwgUINAAAAmEChBgAAAEz4f0/wh9tWv6DiAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "FIGWIDTH=12\n", " \n", "with tempfile.TemporaryDirectory() as tmpdir:\n", " ds2.to_zarr(tmpdir)\n", " x = []\n", " y = []\n", " for vardir in Path(tmpdir).glob(\"*\"):\n", " if os.path.basename(vardir) in ds2.data_vars:\n", " x.append(os.path.basename(vardir))\n", " y.append(sum(f.stat().st_size for f in vardir.glob(\"**/*\")))\n", " plt.figure(figsize=(FIGWIDTH, 4))\n", " plt.title(f\"Total size {round(sum(y)/2**20)}Mi\")\n", " x, y = zip(*sorted(zip(x, y), key=lambda xy: xy[-1], reverse=True))\n", " plt.bar(x, np.array(y)/2**20)\n", " plt.ylabel(\"size [Mi]\")\n", " plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Some variables, like \"total precipitation\" (tp), are 0 most of the time, thus compress much better. Others, like \"2m temperature\" (t2m) and \"wind speed at 10m\" (u/v10), always have some value and are always changing so are harder to compress.\n", "\n", "## Quantization\n", "\n", "What the Pangeo dataset does well, is to quantize the floats to fit in 16-bit (signed) integers. They basically use an offset and scale factor, probably based on the min/max values of the entire dataset, to fit it in this range. We can reduce this range so that compression is easier. Let's see what we can do." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Total size no shuffle level=5 581.085Mi\n", "Total size quantized to int8 level=5 180.651Mi\n", "Total size scale 1 (65536 values) level=5 458.496Mi\n", "Total size scale 10 (6553 values) level=5 345.582Mi\n", "Total size scale 100 (655 values) level=5 234.144Mi\n", "Total size scale 256 (256 values) level=5 182.050Mi\n" ] } ], "source": [ "def range_experiment(name, scale=1, dtype=\"int16\", shuffle=True, cname=\"lz4\", clevel=5, **kwargs):\n", " \n", " encoding = {}\n", " \n", " for k in ds2.data_vars.keys():\n", " v_min, v_max = np.nanmin(ds2[k].values), np.nanmax(ds2[k].values)\n", " \n", " encoding[k] = {\n", " \"compressor\": Blosc(cname=cname, clevel=clevel, shuffle=Blosc.SHUFFLE if shuffle else Blosc.NOSHUFFLE, blocksize=0),\n", " \"filters\": None,\n", " \"missing_value\": -32767.0,\n", " \"_FillValue\": -32767,\n", " \"scale_factor\": (v_max-v_min)/65536 * scale,\n", " \"add_offset\": v_min + (v_max-v_min)/2,\n", " \"dtype\": np.dtype(dtype)\n", " }\n", "\n", " experiment(name + f\" level={clevel}\", encoding, **kwargs)\n", "\n", "range_experiment(\"no shuffle\", shuffle=False)\n", "range_experiment(\"quantized to int8\", scale=256, dtype=\"int8\")\n", "\n", "for scale in [1, 10, 100, 256]:\n", " range_experiment(f\"scale {scale} ({65536//scale} values)\", scale=scale, transpose_order=('latitude', 'time', 'longitude'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "That does yield some benefit, but we give up a lot of resolution for a modest decrease in storage size. Let's continue and see what different compression libraries can do for us." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Total size blosclz level=1 722.452Mi\n", "Total size lz4 level=1 486.358Mi\n", "Total size lz4hc level=1 438.979Mi\n", "Total size snappy level=1 469.271Mi\n", "Total size zlib level=1 408.904Mi\n", "Total size zstd level=1 435.505Mi\n", "Total size blosclz level=5 528.876Mi\n", "Total size lz4 level=5 476.177Mi\n", "Total size lz4hc level=5 423.128Mi\n", "Total size snappy level=5 467.425Mi\n", "Total size zlib level=5 392.028Mi\n", "Total size zstd level=5 382.064Mi\n" ] } ], "source": [ "for clevel in [1,5]:\n", " for cname in blosc.list_compressors():\n", " range_experiment(cname, cname=cname, clevel=clevel)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Results\n", "Let's plot the results of our experiments so far, both the compressed total file size and the time it took to save." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "image/png": "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5IPmvcrGxgY2NjYmqB0RERGZWlJoyHtNJ6L0y3J9WNJSsGBBlC9fHvv37wcA7N+/H+XLl4ednd0HzyMiIiLSsrQr+F7TiSj9slzCMmPGDNSrVw8BAQHo3bs3WrRoAQCYOnUqtmzZgiZNmmDLli349ddflc986DwiIiIiACjUzglm/98UXMvM2hqF2jmZqEREWUeWaxI2ceJETJw48bXp5cqVw86dO9P8zIfOIyIiIgIAmxq1AADBu3chKSwUlgXsUKidkzKdiD5clktYiIiIiEzBpkYt2NSolSk6aBNlJlmuSRgREREREWUdTFiIiIiIiEi1mLAQEREREZFqMWEhIiIiIiLVYqd7IiKibCLi/FkE796FexzFiogyESYsRERE2UDE+bMI3LQBkpAAIOUN7IGbNgAAkxYiUjU2CSMiIsoGgnfvUpIVLUlIQPDuXSYqERFR+jBhISIiygaSQkPeazoRZU4NGzaEvb097O3tsXTpUlMXRy/YJIyIiCgbsLQrmGZyYmlX0ASlISJDOXbsmKmLoHd8wkJERJQNFGrnBDNra51pZtbWKNTOyUQlIiJKHz5hISIiyga0HeuDd+9CEkcJI6JMhAkLERFRNmFToxZsatRC4cL5EBQUaeriEBGlC5uEERERERGRajFhISIiIiIi1WLCQkREREREqsWEhYiIiIiIVIsJCxERERERqRYTFiIiIiIiUi0mLEREREREpFpMWIiIiIiISLWYsBARERERkWoxYSEiIiIiItViwkJERERERKrFhIWIiIiIiFSLCQsREREREakWExYiIiIiIlItJixERERERKRaTFiIiIiIiEi1mLAQEREREZFqMWEhIiIiIiLVYsJCRERERESqxYSFiIiIiIhUiwkLERERERGpFhMWIiIiIiJSLSYsRERERESkWkxYiIiIiIhItZiwEBERERGRajFhISIiIiIi1WLCQkREREREqsWEhYiIiIiIVIsJCxERERERqRYTFiIiIiIiUi0mLEREREREpFpMWIiIiIiISLWYsBARERERkWoxYSEiIiIiItViwkJERERERKrFhIWIiIiIiFSLCQsREREREakWExYiIiIiIlItJixERERERKRaTFiIiIiIiEi1mLAQEREREZFqMWEhIiIiIiLVYsJCRERERESqxYSFiIiIiIhUiwkLERERERGpFhMWIiIiIiJSLSYsRERERESkWkxYiIiIiIhItZiwEBERERGRajFhISIiIiIi1WLCQkREREREqsWEhYiIiIiIVMvS1AWgrCWfTS7kzPF+u1XhwvnSvWxcfBIiI2Lft1hERGQiEefPInj3LtwLC4VlATsUaucEmxq1TF0sIspEmLCQXuXMYYlWI/cabP37FrRBpMHWTkRE+hRx/iwCN22AJCQAAJJCQxC4aQMAMGkhonRjkzAiIiIyiODdu5RkRUsSEhC8e5eJSkREmRETFiIiIjKIpNCQ95pORJSWbJewHD9+HG3btkWbNm3QunVrHDp0CADw8OFDODs7o0mTJnB2dsajR4+Uz7xtHhEREaXN0q7ge00nIkpLtkpYRARjxozB3LlzsXfvXsydOxdjx45FcnIypkyZgi5duuDgwYPo0qULJk+erHzubfOIiIgobYXaOcHM2lpnmpm1NQq1czJRiYgoM8pWCQsAmJubIzIypdt2ZGQkihQpgrCwMNy+fRstW7YEALRs2RK3b99GaGgoQkJC3jgvtYiICDx79kznvxcvXhi3ckRERCpiU6MWivbolfJExcwMlnYFUbRHL3a4J6L3kq1GCTMzM8PixYsxePBg5M6dG9HR0Vi9ejX8/f1RtGhRWFhYAAAsLCxQpEgR+Pv7Q0TeOM/Ozk5Z98aNG7Fs2TKdeFWrVsX27dtRoEAe41XSiN5nOGK1xTVF2TPz98WY6olpqrjZJaap4mblmIVbNUG5Vk2MEuuNZcjC3292jGmquKaqK2WzhCUpKQmurq5YsWIFvvnmG1y+fBnDhw/H3LlzM7zunj17wtHRUWea9f8/Bg8Li0ZSUnKGY7wvQx9YQUGvDzBsjIM5rbjvo3DhfBleR2aIaaq4jJn14maXmKaKy5hZLy5jZr24pqrr+7C0NM+yN8mzVcLi7e2NFy9e4JtvvgEAfPPNN8iVKxdy5MiBwMBAaDQaWFhYQKPR4MWLFyhWrBhE5I3zUrOxsYGNjY0pqkVERERElGVlqz4sH330EQICAuDr6wsAePDgAUJCQlCmTBmUL18e+/fvBwDs378f5cuXh52dHQoWLPjGeUREREREZFjZ6glL4cKFMXXqVAwbNgxmZmYAgFmzZsHW1hZTp07FuHHjsGLFCtjY2GDOnDnK5942j4iIiIiIDCdbJSwA0Lp1a7Ru3fq16eXKlcPOnTvT/Mzb5hERERERkeFku4SFiIjoVRHnzyJ49y7cCwuFZQE7FGrnxKF3iYhUggkLERFlaxHnzyJw0wZIQgIAICk0BIGbNgAAkxYiIhXIVp3uiYiIXhW8e5eSrGhJQgKCd+8yUYmIiCg1JixERJStJYWGvNd0IiIyLiYsRESUrVnaFXyv6UREZFxMWIiIKFsr1M4JZtbWOtPMrK1RqJ2TiUpERESpsdM9ERFla9qO9cG7dyGJo4QREakOExYiIsr2bGrUgk2NWihcOB+CgiJNXRwiIkqFTcKIiIiIiEi1mLAQEREREZFqMWEhIiIiIiLVYsJCRERERESqxYSFiIiIiIhUiwkLERERERGpFhMWIiIiIiJSLSYsRERERESkWkxYiIiIiIhItZiwEBERERGRajFhISIiIiIi1WLCQkREREREqsWEhYiIiIiIVIsJCxERERERqRYTFiIiIiIiUi0mLEREREREpFqWpi4AUUbls8mFnDneb1cuXDhfupeNi09CZETs+xaLiIiIiPSACQtlejlzWKLVyL0GW/++BW0QabC1ExEREdHbsEkYERERERGpFhMWIiIiIiJSLSYsRERERESkWkxYiIiIiIhItZiwEBERERGRajFhISIiIiIi1WLCQkREREREqsWEhYiIiIiIVIsJCxERERERqRYTFiIiIiIiUi0mLEREREREpFpMWIiIiIiISLWYsBARERERkWoxYSEiIiIiItViwkJERERERKrFhIWIiIiIiFSLCQsREREREakWExYiIiIiIlItJixERERERKRaTFiIiIiIiEi1mLAQEREREZFqMWEhIiIiIqJ0CQ8PR7t27VClShWjxWTCQkRERERE6ZInTx788ccf+Prrr40WkwkLERERERGli5WVFWxtbY0akwkLEREREVEW4e/vj2fPnun8FxERkeayc+bMQcOGDWFvb4979+4p0x8+fAhnZ2c0adIEzs7OePTokZFKnzYmLEREREREWUTXrl3RqFEjnf82btyY5rKNGjXC1q1bUaJECZ3pU6ZMQZcuXXDw4EF06dIFkydPNkbR38jSpNGJiIiIiEhvtm7dCo1GozPNxsYmzWUdHBxemxYSEoLbt29j/fr1AICWLVti+vTpCA0NhZ2dnf4LnA58wkJERERElEUUK1YMJUuW1PnvTQlLWvz9/VG0aFFYWFgAACwsLFCkSBH4+/sry/Tq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Wxiy3wzAvjNE78ImYUREREREpFpMWIiIiIiISLWYsBARERERkWoxYSEiIiIiItViwkJERERERKrFhIWIiIiIiFSLCQsREREREakWExYiIiIiIlItJixERERERKRaTFiIiIiIiEi1mLAQEREREZFqMWEhIiIiIiLVsjR1AYiIiIhIVz6bXMiZ4/0u0woXzpfuZePikxAZEfu+xSIyCSYsRFlQ+QhfNAi9CpukaERY5oGXXRV425Q1dbGIiCidcuawRKuRew22/n0L2iDSYGsnU2rYsCGeP38OAHBxccGQIUNMXKKMY8JClMWUj/BF86BzsBINACB/UjSaB50DACYtREREWdyxY8dMXQS9Yx8WoiymQehVJVnRshINGoReNVGJiIiIiD4cExaiLMYmKfq9phMRERGpGRMWoiwmwjLPe00nIiIiUjMmLERZjJddFSSaWehMSzSzgJddFROViIiIiOjDsdM9URaj7VjPUcKIiIgoK2DCQpQFeduUZYJCREREWQKbhBERERERkWoxYSEiIiIiItViwkJERERERKrFhIWIiIiIiFSLCQsREREREakWExYiIiIiIlItJixERERERKRaTFiIiIiIiEi1+OJIIiJKU/kIXzQIvQqbpGhEWOaBl10VvpCUiIiMjgkLERG9pnyEL5oHnYOVaAAA+ZOi0TzoHAAwaSEiIqNikzAiInpNg9CrSrKiZSUaNAi9aqISERFRdsUnLERE7yG7NJOySYp+r+lERESGwicsRETppG0mlT8pGmb4XzOp8hG+pi6a3kVY5nmv6URERIbChIWIKJ2yUzMpL7sqSDSz0JmWaGYBL7sqJioRERFlV2wSRkSUTtmpmZS2mVt2aP5GRETqxoSFiCidIizzIH8ayUlWbSblbVOWCQoREZkcm4QREaUTm0kREREZH5+wEBGlE5tJERERGR8TFiKi98BmUkRERMbFJmFERERERKRaTFiIiIiIiEi1mLAQEREREZFqMWEhIiIiIiLVYsJCRERERESqxYSFiIiIiIhUi8MaE5FelI/w5ftJiIiISO+YsBBRhpWP8EXzoHOwEg0AIH9SNJoHnQMAJi1ERESUIUxYiCjDGoReVZIVLSvRoEHoVYMmLHyqQ0RElPUxYSGiDLNJin6v6frApzpERETZAzvdE1GGRVjmea/p+vC2pzpERESUdTBhIaIM87Kr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WcSxY8dMXQS9Yx8WIiIiIiJSLSYsRERERESkWkxYiIiIiIhItZiwEBERERGRajFhISIiIiIi1WLCQkREREREqsWEhYiIiIiIVIsJCxERERERqRYTFiIiIiIiUi0mLEREREREpFpMWIiIiIiISLWYsBARERERkWoxYSEiIiIiItViwkJERERERKrFhIWIiIiIiFSLCQsREREREakWExYiIiIiIlItJixERERERKRaTFiIiIiIiEi1mLAQEREREZFqWZq6AJQ9lY/wRYPQq7BJikaEZR542VWBt01ZUxeLiIiIiFSGCQsZXfkIXzQPOgcr0QAA8idFo3nQOQBg0kJEREREOtgkjIyuQehVJVnRshINGoReNVGJiIiIiEitmLCQ0dkkRb/XdCIiIiLKvpiwkNFFWOZ5r+lERERElH0xYSGj87KrgkQzC51piWYW8LKrYqISEREREZFasdM9GZ22Yz1HCSMiIiKid2HCQibhbVOWCQoRERERvRObhBERERERkWoxYSEiIiIiItViwkJERERERKrFhIWIiIiIiFSLCQsREREREakWExYiIiIiIlItJixERERERKRaTFiIiIiIiEi1mLAQEREREZFqMWEhIiIiIiLVYsJCRERERESqxYQlnR4+fAhnZ2c0adIEzs7OePTokamLRERERESU5TFhSacpU6agS5cuOHjwILp06YLJkyebukhERERERFmepakLkBmEhITg9u3bWL9+PQCgZcuWmD59OkJDQ2FnZwcAiIiIQEREhM7nrK2tUaRIEVhYmC4vLP9xAYOt29Iy7XoZMuab4poipqHjZpeYb4rLbZp5Y5oqLmNym2bWmG+Ky22aeWO+La6hmPJ609DMRERMXQi1u3XrFsaOHQtPT09lWvPmzTFv3jxUrFgRALB06VIsW7ZM53OdOnXCr7/+atSyEhERERFlJXzCoic9e/aEo6Pja9NjYmKQO3duE5SIiIiIiCjzY8KSDsWKFUNgYCA0Gg0sLCyg0Wjw4sULFCtWTFnGxsYGNjY2JiwlEREREVHWk3Ubu+lRwYIFUb58eezfvx8AsH//fpQvX17pv0JERERERIbBPizp9ODBA4wbNw4RERGwsbHBnDlzULZsWVMXi4iIiIgoS2PCQkREREREqsUmYUREREREpFpMWIiIiIiISLWYsBARERERkWoxYSEiIiIiItVi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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "res = sorted(results, key=lambda x: x[1], reverse=True)[1:]\n", "\n", "plt.figure(figsize=(FIGWIDTH, 8))\n", "plt.title(\"All experiments (sorted by size, ignoring uncompressed)\")\n", "plt.xticks(range(len(res)), rotation=45, horizontalalignment=\"right\")\n", "\n", "ax1 = plt.gca()\n", "ax1.set_ylabel(\"size [MB]\")\n", "ax2 = ax1.twinx()\n", "ax2.set_ylabel(\"time [s]\", color=\"r\")\n", "ax2.grid(False)\n", "ax2.set_yscale(\"log\")\n", "\n", "for i, (name, size, t) in enumerate(res):\n", " ax1.bar(name, size, color=\"b\")\n", " ax2.plot(i, t, 'ro', label=None)\n", "\n", "plt.show();" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is not a proper benchmark, so the \"compression time\" numbers are not very reliable (they jump around a bit from one run to the next), take them with a grain of salt.\n", "\n", "## Influence of dimension order\n", "\n", "As a final optimization, I want to explore the order of the dimensions, as this data is 3-dimensional but saved as a 1-dimensional buffer of bytes. Numeric arrays that change little are easier to compress than arrays that change a lot from one value to the next." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAsYAAAELCAYAAADa9kBCAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAAArCElEQVR4nO3de1yUdf7//ycDggcwhUVFrdUsibQSJdEUSUTxgI7ZGmamm4Vp37ItK7U1EbMDm7afJDtZ2rqapWubSWZu+8lKS1t3LelDmmt4ioOKKSflMLx/f3hzfqEcBr1GRnncbzdvN2bmfb2v1zWvuS6fXFwz42WMMQIAAAAaOFt9FwAAAAB4AoIxAAAAIIIxAAAAIIlgDAAAAEgiGAMAAACSCMYAAACAJIIxgMvYTz/9JLvdrvDwcC1btqzW8ampqXrsscdcmvvuu+/W6tWrL7TEWg0bNkzbtm07r2X//e9/a9CgQQoPD9enn3560Wp2h0u5dgCXDoIxgAu2fft2jRkzRj169FDPnj01ZswY7dy5s77L0ptvvqnIyEjt2LFD48ePd9t63n//fd15551umfujjz5SZGTkeS27cOFC3XXXXdqxY4diY2PrtGxMTIy++uor5+1Dhw4pNDRU5eXl51ULAFwKfOq7AACXtsLCQk2ePFlz5szRkCFDVFZWpu3bt8vX17e+S1NWVpaGDRtW32XUm6ysLF177bX1XYZHKS8vl4+PT633AWiYOGMM4IJkZmZKkuLj4+Xt7a3GjRurb9++uu666ySde3nC2Wce7777bv35z3/WmDFjFB4ersmTJ+uXX37RtGnT1L17d91+++06dOhQtev/5z//qWHDhikiIkJ333239u7dK0kaP368tm3bprlz5yo8PNxZ568dPHhQ48aNU3h4uO655x798ssvlR7/9ttvNWbMGEVERGjEiBFVXtKwd+9eJSUl6dtvv1V4eLgiIiIkSZs2bdLIkSPVvXt3RUdHKzU11blMSUmJHnvsMUVGRioiIkK33367jh49WuX2/frMbWpqqh5++GE98cQTCg8P17Bhw5Senl7lcrGxsTp48KAmT56s8PBwlZaWVnr8wIEDGj9+vCIjIxUZGalp06YpPz9fkvT4448rKyvLuezixYs1btw4SdLNN9+s8PBw7dixQ5L0t7/9TUOGDNHNN9+se++9Vz///LNzHaGhoVq5cqUGDRqkiIgIJScn69dftlrTslu2bNHgwYPVo0cPzZ07VzV9SevOnTuVkJCgiIgI9e3bV3Pnzq20vaGhoVqxYoUGDRqkQYMGadu2berXr5/eeOMN9enTRzNnztSJEyd0//33q1evXrr55pt1//33KycnR5L08ccfa9SoUZXWuXTpUk2ZMqXamgBcogwAXICCggLTs2dP88QTT5hNmzaZ48ePV3p84cKFZtq0ac7bBw8eNJ07dzZlZWXGGGPGjRtnYmNjzf79+01+fr4ZMmSIGTRokNmyZYspKyszjz/+uJkxY0aV6/7pp5/MTTfdZDZv3mxKS0vNG2+8YWJjY01JSYlz7lWrVlVb+x133GGeffZZU1JSYr755hvTrVs3Z605OTmmZ8+eZtOmTcbhcJjNmzebnj17mry8vHPmXrNmjRkzZkylubdu3Wp27dplHA6H+eGHH0zv3r3NP/7xD2OMMStXrjT333+/KS4uNuXl5SY9Pd0UFBRUWWP//v3Nli1bnM9l165dzaZNm0x5ebmZP3++GT16dLXb9+tlz6553759ZvPmzaakpMTk5eWZsWPHmnnz5lW77Nl9M8aYf/zjHyY2Ntb897//NWVlZWbRokUmISHB+Xjnzp3NpEmTzIkTJ8zPP/9sIiMjzeeff17rsnl5eaZbt27m448/NqWlpWbp0qUmLCys2l6mp6ebHTt2mLKyMnPw4EEzePBgs3Tp0kp1/P73vze//PKLOXnypNm6dasJCwszf/rTn0xJSYk5efKkOXbsmNmwYYMpLi42BQUF5qGHHjJTpkwxxhhTUlJibr75ZvPf//7XOafdbjcbNmyo9rkHcGnyqDPGKSkpiomJUWhoqH788cdax//nP/+R3W53/uvbt69uu+22i1ApgDP8/f31zjvvyMvLS0899ZR69+6tyZMnV3sGtCqjRo3SVVddpYCAAPXr109XXnmlbrnlFvn4+Gjw4MHKyMiocrn169crOjpaffr0UaNGjXTvvffq1KlTzrOZNcnKylJ6eroefvhh+fr66uabb1ZMTIzz8bVr16pfv36Kjo6WzWZTnz591LVrV33++ecubVNkZKRCQ0Nls9l03XXXadiwYfrmm28kST4+Pjp+/Lj2798vb29vde3aVf7+/i7N26NHD0VHR8vb21t2u127du1yabmz/fa3v1WfPn3k6+urwMBA3XPPPfrXv/5VpzneffddTZo0SZ06dZKPj48mT56sH374odKZ38TERDVv3lxt27ZVZGSks96alv3iiy907bXXavDgwWrUqJEmTJig3/zmN9XW0bVrV3Xr1k0+Pj5q3769EhISztmWSZMmqUWLFmrcuLEkyWazaerUqfL19VXjxo3VsmVLxcXFqUmTJvL399eUKVOcc/j6+mrIkCH68MMPJUl79uzRzz//rP79+9fp+QLg+TzqoqoBAwZo/Pjxuuuuu1wa3717d61du9Z5+4EHHlCPHj3cVR6AanTq1EnPP/+8pNOXFjz++ON69tln9eKLL7q0/K9Dj5+fX6XbjRs3VnFxcZXLHT58WG3btnXettlsCgkJUW5ubq3rPHz4sJo3b66mTZs672vbtq2ys7MlnQ7OGzZs0GeffeZ8vLy83OU3wn333XeaP3++9uzZo7KyMpWWlmrw4MGSJLvdrpycHD366KPKz8/XiBEj9Mgjj6hRo0a1znv2c1NSUnJe18gePXpUzzzzjLZv366ioiIZY9S8efM6zZGVlaVnn31WKSkpzvuMMcrNzVW7du0kScHBwc7HmjRpoqKiolqXPXz4sNq0aeO838vLSyEhIdXWkZmZqeeff17ff/+9Tp48KYfDoS5dulQac/byLVu2lJ+fn/P2yZMn9dxzz+nLL7/UiRMnJElFRUVyOBzy9vbWbbfdpkcffVR/+MMftHbtWg0ZMsQjrqMHYC2PCsZnrs0725n/YM4cUKdOnapbb7210pi8vDxt2bJFc+fOdXeZAGrQqVMnjRo1Su+9956k02Ho1KlTzsfrcia5Nq1atar01yVjjLKzs9W6detalw0ODlZ+fr6Ki4ud4TgrK0teXl6STgcpu92uefPm1TrXmWV+bdq0aRo3bpzefPNN+fn56ZlnnnFew9yoUSM9+OCDevDBB3Xo0CFNmjRJHTt21OjRo13abiu8+OKL8vLy0rp169SiRQt9+umnNR4/q9rGkJAQTZ48WSNGjKjz+mtadv/+/c7re6X/v6/VmTNnjq6//notWLBA/v7+evvtt/XJJ5/UWP/Zt5csWaLMzEytWrVKwcHB+uGHHzRy5Ejntc3dunVTo0aNtH37dqWlpWn+/Pl13mYAns+jLqWoSn5+vpKSkrRgwQK9//77eu211zR79mznm0TO+OCDD9SnT58a/9wGwHp79+7VkiVLnEEmOztbaWlpuummmyRJYWFh+te//qWsrCwVFBTo9ddft2zdQ4YM0eeff66vv/5aZWVlWrJkiXx9fRUeHl7rsu3atVPXrl2Vmpqq0tJSbd++vdLZ4REjRuizzz7Tl19+KYfDoZKSEm3btq1SYDsjKChIubm5ld7wVVRUpCuuuEJ+fn7auXOn0tLSnI9t3bpVu3fvlsPhkL+/v3x8fGSzXdzDcVFRkZo2baqAgADl5ubqzTffrPT4b37zGx08eNB5OzAwUDabrdJ9Y8aM0RtvvKE9e/ZIkgoKCvTxxx+7tP6alo2OjtaePXu0ceNGlZeXa9myZTX+QlVUVKRmzZqpWbNm2rt3r1auXOnak3DWHH5+fmrevLmOHz+ul19++ZwxI0eO1Ny5c+Xj41PtiRwAlzaPD8Y7duzQoUOHlJiYKLvdrsTERHl5eWn//v2Vxr3//vu6/fbb66lKoOHy9/fXd999p9GjR6tbt26644471LlzZ82YMUOS1KdPHw0dOlQjRozQqFGjLL0u8+qrr9YLL7ygp59+Wr169dJnn32m1157zeU/cS9YsEDfffedIiMjtWjRIo0cOdL5WEhIiF555RW9/vrr6t27t6Kjo/XWW2+poqLinHl69eqla665Rn379nVeapGUlKSFCxcqPDxcixYt0pAhQ5zjjx49qqlTp6pHjx4aOnSoevbsKbvdfmFPRh09+OCDysjIUEREhCZNmqRBgwZVenzSpEl69dVXFRERobfeektNmjTR5MmTdeeddyoiIkLffvutBg4cqPvuu0+PPvqounfvrvj4eH3xxRcurb+mZQMDA/XSSy9pwYIFioyM1P79+9W9e/dq55o+fbrS0tLUvXt3PfXUUxo6dGidn48JEyaopKREvXr1UkJCgqKios4ZY7fbtWfPnvM6Qw7g0uBlTA2fgVNPYmJi9Nprr6lz587atGmTFi9erBUrVlQ7/ttvv9WDDz6oTZs28VmUAAC3OHXqlHr37q2///3v6tChQ32XA8ANPP6McXh4uPbv36+tW7c679u5c2elz7Rcs2aNRowYQSgGALjNypUrdcMNNxCKgcuYR50xnjdvnjZu3KijR4+qZcuWatGihT766CPt3LlTL7zwgk6cOKGysjJdeeWVeu2112Sz2XTq1Cn16dNHq1atUqdOnep7EwAAl6GYmBgZY7Ro0SJdf/319V0OADfxqGAMAAAA1BePv5QCAAAAuBgIxgAAAIAIxgAAAIAkD/vmu19+KVJFBZc8VyUoyF95eYX1XQZqQI88Hz3yfPTI89Ejz0ePamazeally2ZVPuZRwbiiwhCMa8Bz4/nokeejR56PHnk+euT56NH54VIKAAAAQC4G45SUFMXExCg0NFQ//vhjjWN/+ukn3XTTTUpJSbGkQAAAAOBicCkYDxgwQCtWrFC7du1qHOdwOJSUlKTY2FhLigMAAAAuFpeuMY6IiHBpsjfeeEO33nqriouLVVxcfEGFAQAAABeTZW++27VrlzZv3qxly5bplVdeOa85goL8rSrnshQcHFDfJaAW9Mjz0SPPR488Hz3yfPTo/FgSjMvKyvTUU0/pueeek7e393nPk5dXyLsoqxEcHKAjRwrquwzUgB55Pnrk+eiR56NHno8e1cxm86r2ZKwlwfjIkSM6cOCAJk2aJEnKz8+XMUaFhYV6+umnrVgFAAAA4FaWBOO2bdtq27ZtztupqakqLi7W9OnTrZgeAHCBApo3UWM/j/ro+mpdCn8CPlVSroL8k/VdBi4y9iNreeJ+5FJ3582bp40bN+ro0aO655571KJFC3300UdKTEzU1KlTdcMNN7i7TgDABWjs56Ph09bWdxmXjXUL7OIP1Q0P+5G1PHE/cikYz5o1S7NmzTrn/sWLF1c5/qGHHrqwqgAAAICLjG++AwAAAEQwBgAAACQRjAEAAABJBGMAAABAEsEYAAAAkEQwBgAAACQRjAEAAABJFn3z3aXuUvkmG77FBp7qUtmHJPYjAED1Lo3/ydyMb7Kxjid+iw3cj33IWuxHAFA/uJQCAAAAEMEYAAAAkEQwBgAAACQRjAEAAABJBGMAAABAEsEYAAAAkEQwBgAAACQRjAEAAABJBGMAAABAEsEYAAAAkEQwBgAAACQRjAEAAABJLgbjlJQUxcTEKDQ0VD/++GOVYxYtWqRhw4Zp+PDhGjVqlL788ktLCwUAAADcyceVQQMGDND48eN11113VTvmxhtv1MSJE9WkSRPt2rVL48aN0+bNm9W4cWPLigUAAADcxaVgHBERUeuYqKgo58+hoaEyxuj48eNq06bN+VcHAAAAXCQuBeO6+uCDD3TVVVfVORQHBfm7oxxcZMHBAfVdQr1pyNsOa/Fa8nwNuUcNedthLU97LVkejL/55hu99NJLWrJkSZ2XzcsrVEWFsbqkWnlaUy51R44U1HcJ9SI4OKBBbzusZfVriR5ZryHv7w1522Gt+ngt2Wxe1Z6MtTQY79ixQ48//rheeeUVXX311VZODQAAALiVZR/XtnPnTj3yyCNauHChunTpYtW0AAAAwEXhUjCeN2+e+vXrp5ycHN1zzz0aNmyYJCkxMVHp6emSpOTkZJ06dUqzZ8+W3W6X3W7X7t273Vc5AAAAYCGXLqWYNWuWZs2adc79ixcvdv68Zs0a66oCAAAALjK++Q4AAAAQwRgAAACQRDAGAAAAJBGMAQAAAEkEYwAAAEASwRgAAACQRDAGAAAAJBGMAQAAAEkEYwAAAEASwRgAAACQRDAGAAAAJBGMAQAAAEkEYwAAAEASwRgAAACQRDAGAAAAJBGMAQAAAEkEYwAAAEASwRgAAACQRDAGAAAAJBGMAQAAAEkEYwAAAECSC8E4JSVFMTExCg0N1Y8//ljlGIfDoeTkZMXGxmrgwIFavXq15YUCAAAA7lRrMB4wYIBWrFihdu3aVTtm3bp1OnDggDZu3Kj33ntPqampOnTokKWFAgAAAO5UazCOiIhQSEhIjWPWr1+v0aNHy2azKTAwULGxsdqwYYNlRQIAAADu5mPFJNnZ2Wrbtq3zdkhIiHJycuo8T1CQvxXloJ4FBwfUdwn1piFvO6zFa8nzNeQeNeRth7U87bVkSTC2Sl5eoSoqzEVfr6c15VJ35EhBfZdQL4KDAxr0tsNaVr+W6JH1GvL+3pC3Hdaqj9eSzeZV7clYSz6VIiQkRFlZWc7b2dnZatOmjRVTAwAAABeFJcF48ODBWr16tSoqKnTs2DF9+umniouLs2JqAAAA4KKoNRjPmzdP/fr1U05Oju655x4NGzZMkpSYmKj09HRJkt1uV/v27TVo0CDdcccd+n//7//pyiuvdG/lAAAAgIVqvcZ41qxZmjVr1jn3L1682Pmzt7e3kpOTra0MAAAAuIj45jsAAABABGMAAABAEsEYAAAAkEQwBgAAACQRjAEAAABJBGMAAABAEsEYAAAAkEQwBgAAACQRjAEAAABJBGMAAABAEsEYAAAAkEQwBgAAACQRjAEAAABJBGMAAABAEsEYAAAAkEQwBgAAACQRjAEAAABJBGMAAABAEsEYAAAAkEQwBgAAACQRjAEAAABJko8rgzIzMzVjxgwdP35cLVq0UEpKijp06FBpTF5enmbOnKns7GyVl5crMjJSs2bNko+PS6sAAAAA6pVLZ4yTkpI0duxYffLJJxo7dqxmz559zpjXXntNnTp10rp16/Thhx/q//7v/7Rx40bLCwYAAADcodZgnJeXp4yMDMXHx0uS4uPjlZGRoWPHjlUa5+XlpaKiIlVUVKi0tFRlZWVq3bq1e6oGAAAALFbrdQ7Z2dlq3bq1vL29JUne3t5q1aqVsrOzFRgY6Bz3wAMP6KGHHlLfvn118uRJ3XXXXerRo0edigkK8q9j+fBEwcEB9V1CvWnI2w5r8VryfA25Rw1522EtT3stWXYB8IYNGxQaGqq//OUvKioqUmJiojZs2KDBgwe7PEdeXqEqKoxVJbnM05pyqTtypKC+S6gXwcEBDXrbYS2rX0v0yHoNeX9vyNsOa9XHa8lm86r2ZGytl1KEhIQoNzdXDodDkuRwOHT48GGFhIRUGrd8+XKNGDFCNptNAQEBiomJ0bZt2ywoHwAAAHC/WoNxUFCQwsLClJaWJklKS0tTWFhYpcsoJKl9+/b64osvJEmlpaX6+uuvde2117qhZAAAAMB6Ln0qxZw5c7R8+XLFxcVp+fLlSk5OliQlJiYqPT1dkvTkk0/q3//+t4YPH66RI0eqQ4cOuuOOO9xXOQAAAGAhl64x7tSpk1avXn3O/YsXL3b+fNVVV2np0qXWVQYAAABcRHzzHQAAACCCMQAAACCJYAwAAABIIhgDAAAAkgjGAAAAgCSCMQAAACCJYAwAAABIcvFzjIH6FNC8iRr7XRov1eDggPouoVanSspVkH+yvssAcBaOddbiWIfzcWnsgWjQGvv5aPi0tfVdxmVj3QK7Cuq7CADn4FhnLY51OB9cSgEAAACIYAwAAABIIhgDAAAAkgjGAAAAgCSCMQAAACCJYAwAAABIIhgDAAAAkgjGAAAAgCSCMQAAACCJYAwAAABIIhgDAAAAkgjGAAAAgCQXg3FmZqYSEhIUFxenhIQE7du3r8px69ev1/DhwxUfH6/hw4fr6NGjVtYKAAAAuI2PK4OSkpI0duxY2e12rV27VrNnz9ayZcsqjUlPT9fLL7+sv/zlLwoODlZBQYF8fX3dUjQAAABgtVrPGOfl5SkjI0Px8fGSpPj4eGVkZOjYsWOVxr399tuaOHGigoODJUkBAQHy8/NzQ8kAAACA9Wo9Y5ydna3WrVvL29tbkuTt7a1WrVopOztbgYGBznF79+5V+/btddddd6m4uFgDBw7UlClT5OXl5XIxQUH+57EJ8DTBwQH1XQJqQY88Hz3yfPTI89Ejz+dpPXLpUgpXOBwO7d69W0uXLlVpaanuu+8+tW3bViNHjnR5jry8QlVUGKtKcpmnNeVSd+RIgaXz0R/r0SPPR488Hz3yfPTI81ndI1fYbF7Vnoyt9VKKkJAQ5ebmyuFwSDodgA8fPqyQkJBK49q2bavBgwfL19dX/v7+GjBggHbu3GlB+QAAAID71RqMg4KCFBYWprS0NElSWlqawsLCKl1GIZ2+9njz5s0yxqisrExbt27Vdddd556qAQAAAIu59HFtc+bM0fLlyxUXF6fly5crOTlZkpSYmKj09HRJ0rBhwxQUFKShQ4dq5MiRuuaaa/S73/3OfZUDAAAAFnLpGuNOnTpp9erV59y/ePFi5882m00zZ87UzJkzrasOAAAAuEj45jsAAABABGMAAABAEsEYAAAAkEQwBgAAACQRjAEAAABJBGMAAABAEsEYAAAAkEQwBgAAACQRjAEAAABJBGMAAABAEsEYAAAAkEQwBgAAACQRjAEAAABJBGMAAABAEsEYAAAAkEQwBgAAACQRjAEAAABJBGMAAABAEsEYAAAAkEQwBgAAACQRjAEAAABJLgbjzMxMJSQkKC4uTgkJCdq3b1+1Y3/66SfddNNNSklJsapGAAAAwO1cCsZJSUkaO3asPvnkE40dO1azZ8+ucpzD4VBSUpJiY2MtLRIAAABwt1qDcV5enjIyMhQfHy9Jio+PV0ZGho4dO3bO2DfeeEO33nqrOnToYHmhAAAAgDv51DYgOztbrVu3lre3tyTJ29tbrVq1UnZ2tgIDA53jdu3apc2bN2vZsmV65ZVXzquYoCD/81oOniU4OKC+S0At6JHno0eejx55Pnrk+TytR7UGY1eUlZXpqaee0nPPPecM0OcjL69QFRXGipLqxNOacqk7cqTA0vnoj/XokeejR56PHnk+euT5rO6RK2w2r2pPxtYajENCQpSbmyuHwyFvb285HA4dPnxYISEhzjFHjhzRgQMHNGnSJElSfn6+jDEqLCzU008/bdFmAAAAAO5TazAOCgpSWFiY0tLSZLfblZaWprCwsEqXUbRt21bbtm1z3k5NTVVxcbGmT5/unqoBAAAAi7n0qRRz5szR8uXLFRcXp+XLlys5OVmSlJiYqPT0dLcWCAAAAFwMLl1j3KlTJ61evfqc+xcvXlzl+IceeujCqgIAAAAuMr75DgAAABDBGAAAAJBEMAYAAAAkEYwBAAAASQRjAAAAQBLBGAAAAJBEMAYAAAAkEYwBAAAASQRjAAAAQBLBGAAAAJBEMAYAAAAkEYwBAAAASQRjAAAAQBLBGAAAAJBEMAYAAAAkEYwBAAAASQRjAAAAQBLBGAAAAJBEMAYAAAAkEYwBAAAASQRjAAAAQJLk48qgzMxMzZgxQ8ePH1eLFi2UkpKiDh06VBqzaNEirV+/XjabTY0aNdIjjzyiqKgod9QMAAAAWM6lYJyUlKSxY8fKbrdr7dq1mj17tpYtW1ZpzI033qiJEyeqSZMm2rVrl8aNG6fNmzercePGbikcAAAAsFKtl1Lk5eUpIyND8fHxkqT4+HhlZGTo2LFjlcZFRUWpSZMmkqTQ0FAZY3T8+HHrKwYAAADcoNYzxtnZ2WrdurW8vb0lSd7e3mrVqpWys7MVGBhY5TIffPCBrrrqKrVp06ZOxQQF+ddpPDxTcHBAfZeAWtAjz0ePPB898nz0yPN5Wo9cupSiLr755hu99NJLWrJkSZ2XzcsrVEWFsbqkWnlaUy51R44UWDof/bEePfJ89Mjz0SPPR488n9U9coXN5lXtydhaL6UICQlRbm6uHA6HJMnhcOjw4cMKCQk5Z+yOHTv0+OOPa9GiRbr66qsvsGwAAADg4qk1GAcFBSksLExpaWmSpLS0NIWFhZ1zGcXOnTv1yCOPaOHCherSpYt7qgUAAADcxKXPMZ4zZ46WL1+uuLg4LV++XMnJyZKkxMREpaenS5KSk5N16tQpzZ49W3a7XXa7Xbt373Zf5QAAAICFXLrGuFOnTlq9evU59y9evNj585o1a6yrCgAAALjI+OY7AAAAQARjAAAAQBLBGAAAAJBEMAYAAAAkEYwBAAAASQRjAAAAQBLBGAAAAJBEMAYAAAAkEYwBAAAASQRjAAAAQBLBGAAAAJBEMAYAAAAkEYwBAAAASQRjAAAAQBLBGAAAAJBEMAYAAAAkEYwBAAAASQRjAAAAQBLBGAAAAJBEMAYAAAAkEYwBAAAASS4G48zMTCUkJCguLk4JCQnat2/fOWMcDoeSk5MVGxurgQMHavXq1VbXCgAAALiNS8E4KSlJY8eO1SeffKKxY8dq9uzZ54xZt26dDhw4oI0bN+q9995TamqqDh06ZHnBAAAAgDv41DYgLy9PGRkZWrp0qSQpPj5eTz/9tI4dO6bAwEDnuPXr12v06NGy2WwKDAxUbGysNmzYoPvuu8/lYmw2r/PYBGu0atmk3tZ9uXFHH+mPteiR56NHno8eeT565PnqI/vVtM5ag3F2drZat24tb29vSZK3t7datWql7OzsSsE4Oztbbdu2dd4OCQlRTk5OnQpt2bJZncZb6a1Zg+pt3ZeboCB/y+ekP9aiR56PHnk+euT56JHnc0ePLgRvvgMAAADkQjAOCQlRbm6uHA6HpNNvsjt8+LBCQkLOGZeVleW8nZ2drTZt2lhcLgAAAOAetQbjoKAghYWFKS0tTZKUlpamsLCwSpdRSNLgwYO1evVqVVRU6NixY/r0008VFxfnnqoBAAAAi3kZY0xtg/bu3asZM2YoPz9fzZs3V0pKiq6++molJiZq6tSpuuGGG+RwODR37lxt2bJFkpSYmKiEhAS3bwAAAABgBZeCMQAAAHC54813AAAAgAjGAAAAgCSCMQAAACCJYAwAAABIIhhfkNDQUBUVFdU4Jj8/X4sXL65xzN13363PPvvMytL09ttvKy8vz3l75cqVevvtty1dx6XAqh69//77yszMdN7+5z//qZSUlAuuLzU11ZJ5LmWu9KguDh06pMjISJfGvffeezWOYT86zeoeVbXP/fGPf9T27dsveO6YmBj9+OOPtY5LTU1VaWnpBa/PU/x6e1566SWtX7/+gud09f+ms/eTqmpr6Mc5qX57VBcNdR86g2DsZvn5+XrzzTcv+nqXLVtW6UB155136ve///1Fr+NS4EqP/v73v2vfvn3O2wMGDND06dPdXBnc6eeff641GLMfuUdV+9wzzzyjiIiIi1bDyy+/rLKysou2Pnf79fY8/PDDGjp06EVb99n7CapWnz1yh8ttHzrDp74LuFykpKTom2++UVlZmVq2bKlnn31W7dq109y5c1VQUCC73a4mTZro3XffrXGeo0ePKikpSQcOHJAk3XvvvRo5cqSk07/F2e12ffXVVzpy5IgmTpyocePGnTPHq6++qsOHD2vq1Kny8/PTggUL9PHHH6u4uFjTp0/X+++/r7S0NAUEBGj37t1q3bq1nnrqKaWkpOjAgQPq2rWr5s+fLy8vL8ufp/p0vj1as2aNvv/+e82bN0//8z//o+nTpysnJ0ebNm3SwoULtW3bNj3zzDO68cYb9d1338nHx0d/+tOf9PLLL2vPnj0KCQlRamqqmjZtWmN9DodD8+fP15dffilJioqK0mOPPSZvb2/NmDFDvr6+2rdvn3JyctStWzelpKRcdj3auXOnnnnmGRUXF6tp06b64x//qBtvvFGHDh3S7bffrjFjxujzzz/XyZMnXQ5S06ZNU2ZmpsrKynTVVVfp2Wef1RVXXKG5c+fq0KFDstvt+u1vf6uFCxdWWo79qGpW9Kiqfe7uu+/WxIkT1b9//0qv94MHD2rgwIHq37+/UlNTlZOTowkTJmjChAm11rpkyRJ99NFHcjgc8vPz05w5cxQWFqbk5GRJ0pgxY2Sz2fTXv/5VzZs3t/y5uljO3p527drplltu0bhx45SamqqffvpJhYWF2rdvn7p06aJJkybp+eefV1ZWlgYOHOjSL/nr1q3TsmXLnEFo+vTp6t27d5X7yTXXXFPtPA31OHcxemRFfjhbQ9mHKjE4b507dzaFhYXGGGPy8vKc969atcr84Q9/MMYYc/DgQdOzZ88a5xk3bpz53//9X2OMMQ8//LD585//bIwxJjc31/Tp08fs3r3bGGNM//79zfPPP++ct1u3bs71n61///7O5YwxZuHChc5l16xZYyIiIkx2drYxxphJkyaZESNGmBMnTpiysjITHx9vtmzZUqfnwlO5o0fGnH4OH3roIWOMMVu3bjXXX3+9ycjIMMYYM2fOHBMVFeV8fu+77z6zatWqKuf9dV9WrFhhJkyYYEpKSkxJSYkZP368WbFihTHGmOnTp5sxY8aYU6dOmZKSEjN06FCzefPmOj8fnuhMj0pKSkx0dLT56quvjDHGbNmyxURHR5uSkhJz8OBB07lzZ2cP1q5daxISEqqc7+x+/rrvL774onnhhReMMaf7dtttt9VYG/vRae7ukTGV97Ezr/eSkhJTXFxsevXqZWbMmGEcDofJyclx+dj3695v2bLFjB49+pxtulz8enumT59u/vrXvxpjTr9mBw4caPLz8015ebkZPny4mThxoikpKTFFRUWmV69eJjMzs8o5f92TY8eOmYqKCmOMMXv37jVRUVHOcWfvJ2fjOHeau3vkjvzQkPahMzhjbJEvvvhC77zzjoqLi1VeXn7e83z99deaMWOGJKlVq1aKjo7Wtm3b1LlzZ0ly/umlffv2at68uXJyctSpU6c6r6d79+5q06aNJCksLEzt2rVz/rZ33XXXaf/+/brlllvOezs8kVU9qkrHjh0VFhYmSbr++uuVlZXlfH67dOmi/fv31zrH119/rdtuu02+vr6SpFGjRunTTz/V2LFjJUmxsbHy8/NzruPAgQPq06ePpdtRnzIzM9WoUSP17t1bknTLLbeoUaNGyszMVLNmzdS0aVP1799fkpxnklyxdu1arVu3TmVlZSouLlaHDh0sq7mh7Ufu6lFVYmNjnftCx44dFR0dLZvNptatW7t87Pv+++/1+uuv68SJE/Ly8qp0OVRD0rdvXwUEBEg6fb34ddddJ19fX/n6+qpjx446cOBArfvFwYMHNW3aNOXm5srHx0dHjx7VkSNHFBwcXKdaGvpxrjpW9Mgd+aEh7kMEYwv8/PPPeu655/S3v/1NV155pf7zn//oscceq3Ls7t279cQTT0iSIiMj9eSTT9ZpXWcOGJLk7e0th8OhL7/8UvPnz5ckDR8+XPfdd1+d56lq3suJu3t05iAvVf18lpSUSJJGjx6t0tJSNWvWTO+8806dtuFy71Ftfv0c22w25y83r776qjZs2CBJmjlzptq3b+8ct337dq1cuVLvvvuuAgMDtW7dOq1atarK+dmPLtz59Kg6rjy3NfWstLRUDz/8sJYvX64uXbooNzdX/fr1u7ANvES58lzWdtx79NFHNWPGDMXGxqqiokI33XST87h2No5zdWdFj+q6DvahqhGMLVBYWKhGjRopODhYFRUVla5R9ff316lTp1ReXi4fHx+FhoZq7dq11c7Vu3dvrVq1SlOnTtWRI0f0+eef1/pmn6ioKEVFRVW6r1mzZiooKLig7bqcXGiPrHo+V69eXe1jvXv31gcffOD8rf6DDz7QoEGDLnidl4qOHTuqrKxMW7duVa9evfT111+rvLxcHTt21OHDh6tdbsqUKZoyZYrz9qFDh5w/5+fny9/fXy1atFBpaanWrFnjfMzf31+FhYXO2+xHtbOqR8ePH6+0z52vqnp2RmlpqcrLyxUSEiJJ5wS0Zs2aqbCwUM2aNTvv9XuSC92e2v5vKigocP5Cs2bNmkqfRnD2fsJxrmru7pFV+eGMhrYPnUEwtkBoaKgGDx6soUOHqmXLloqOjnZ+7FCLFi00fPhwDR8+XFdccUWtb76bNWuWZs+ereHDh0uSHnvsMV177bV1rmn8+PF68skn1bhxYy1YsKDuG3WZudAeJSQk6Pnnn9dbb73ltk+jSEhI0IEDB3TbbbdJOv2ntTvuuMMt6/JEvr6+WrhwYaU3dr300kuVzkLWVVRUlD788EPFxcWpZcuWioiIUHp6uqTTr4mOHTsqPj5eV1999TlvvpPYj85mVY/qelw8H/7+/po6dap+97vfqUWLFoqLi6v0+MSJEzV+/Hg1btz4snjj0K+3p127dpbPP3PmTD3wwAO64oorFBUVpRYtWjgfO3s/qenNdw35OOfuHlmVH85oaPvQGV7GGFPfRQAAAAD1jc8xBgAAAEQwBgAAACQRjAEAAABJBGMAAABAEsEYAAAAkEQwBgAAACQRjAEAAABJBGMAAABAkvT/Aa61GhqeLgMqAAAAAElFTkSuQmCC\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig = plt.figure(figsize=(FIGWIDTH, 4))\n", "plt.title(\"Sum of deltas in flattened array\")\n", "stats = []\n", "labels = []\n", "\n", "for coords in permutations(list(ds2.coords)):\n", " dst = ds2.t2m.transpose(*coords)\n", " label = \"-\".join(c[:3] for c in coords)\n", " plt.bar(label, np.abs(np.diff(dst.data.ravel())).sum(), label=label, color=\"b\")\n", "\n", "plt.show();" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Total size ('latitude', 'longitude', 'time') level=5 509.837Mi\n", "Total size ('latitude', 'time', 'longitude') level=5 458.496Mi\n", "Total size ('longitude', 'latitude', 'time') level=5 519.348Mi\n", "Total size ('longitude', 'time', 'latitude') level=5 488.550Mi\n", "Total size ('time', 'latitude', 'longitude') level=5 476.177Mi\n", "Total size ('time', 'longitude', 'latitude') level=5 505.325Mi\n" ] } ], "source": [ "for coords in permutations(list(ds2.coords)):\n", " range_experiment(str(coords), transpose_order=coords, record=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As the data is a simple array when it is compressed, we want the slowest changing dimensions last so it is most efficiently compressed. We see the same trend in the plot, with longitude seeming to change most slowly, then time, then latitude. (This might be different for different datasets and resolutions.) The file sizes after compression seem to tell the same story.\n", "\n", "Lessons learned:\n", "- The byte shuffling that Blosc can do is very effective\n", "- Quantizing a float32 by fitting its range in an int16 is very effective (more effective encodings can be designed for specific values, but it's hard to improve the effectiveness of this int16 quantization approach)\n", "- Ordering the dimensions from fastest to slowest changing makes a significant difference\n", "- Compression algorithms can yield some improvement, generally the Blosc default of lz4 at level 5 is quite effective and fast\n", "- It might be interesting to test decompression speed, did not do that here" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.5" }, "nikola": { "date": "2020-11-09 20:00:00 UTC", "slug": "compress-zarr-meteo", "title": "Compress Zarr meteo data for cheap blob storage" } }, "nbformat": 4, "nbformat_minor": 4 }