Repository: pytorch
Issue: Caching Support for class Dataset
Labels: module: dataloader,triaged,enhancement

## 🚀 Feature
<!-- A clear and concise description of the feature proposal -->
For datasets that fit into memory, but the samples are loaded individually a cache could decrease the time needed to fetch the samples. In each call to the dataset the cache should be checked for the existence of the object to be loaded and if possible return the cached sample.
## Motivation

<!-- Please outline the motivation for the proposal. Is your feature request related to a problem? e.g., I'm always frustrated when [...]. If this is related to another GitHub issue, please link here too -->
Loading data from the file system or even worse from network storage can take a considerable amount of time. Since training speed is limited by the time it takes to load the requested data, speed-ups on the data fetching side can lead to improved training time and higher utilization of the computational resources.
## Pitch

<!-- A clear and concise description of what you want to happen. -->
A simple function like the following could handle the caching:
```
    def get_item(self, index):
        if index in self.cache.keys():
            return self.cache[index]
        sample = self.load_item(index)
        self.cache[index] = sample
        return sample
```
However, for this sample to work the function `load_item` needs to be implemented by the user just like using `Dataset` directly.

## Additional context

<!-- Add any other context or screenshots about the feature request here. -->
I started defining the required class, however, found that my implementation requires to much action using this as a base class.
I would appreciated any suggestions to reduce the complexity of this proposal:
````
class CachingDataset(Dataset):
    r"""A caching :class:`Dataset`.

    All subclasses should overwrite :meth:`load_item`, supporting fetching a
    data sample from file.
    Subclasses could also optionally overwrite
    :meth:`__len__`, which is expected to return the size of the dataset by many
    :class:`~torch.utils.data.Sampler` implementations and the default options
    of :class:`~torch.utils.data.DataLoader`.
    For datasets that fit into the memory this allows faster data loading from the second batch on
    by caching the loaded data into the `cache`.

    .. note::
      Performance gains will be visible from the second epoch on.

    Example 1: Loading data from cache if available using  :meth:`get_item`::

        >>> class MyCachingDataset(torch.utils.data.CachingDataset):
        ...     def __init__(self):
        ...         super().__init__()
        ...
        ...     def load_item(self, index):
        ...         sample = read_from_file(self.data[index])
        ...         return sample
    """
    def __init__(self):
        self.cache = dict()

    def __getitem__(self, index):
        return self.get_item(index)

    def get_item(self, index):
        if index in self.cache.keys():
            return self.cache[index]
        sample = self.load_item(index)
        self.cache[index] = sample
        return sample

    def load_item(self, index):
        raise NotImplementedError
```

cc @SsnL