Repository: Lightning-AI/pytorch-lightning
File: src/lightning/pytorch/trainer/connectors/data_connector.py (Python)

Code before:
                    def __len__(self):
                        return 1

                sampler = SingleBatchSampler(first_batch)
            else:
                sampler = SequentialSampler(dl.dataset)

            # Create a new dataloader with the new sampler
            new_dl = DataLoader(
                dataset=dl.dataset,
                batch_size=dl.batch_size,
                sampler=sampler,
                num_workers=dl.num_workers,
                collate_fn=dl.collate_fn,
                pin_memory=dl.pin_memory,
                drop_last=dl.drop_last,
                timeout=dl.timeout,
                worker_init_fn=dl.worker_init_fn,
                multiprocessing_context=dl.multiprocessing_context,
                generator=dl.generator,
                prefetch_factor=dl.prefetch_factor,
                persistent_workers=dl.persistent_workers,
            )
            updated.append(new_dl)
        else:
            updated.append(dl)

    combined_loader.flattened = updated


@dataclass
class _DataLoaderSource:
    """Stores the information where the dataloaders come from.

    The source can be

    1. from a ``*_dataloader()`` method on the :class:`~lightning.pytorch.core.LightningModule`,
    2. from a ``*_dataloader()`` method on the :class:`~lightning.pytorch.core.datamodule.LightningDataModule`,
    3. a direct instance of a :class:`~torch.utils.data.DataLoader` or supported collections thereof.

    Arguments:
        instance: A LightningModule, LightningDataModule, or (a collection of) iterable(s).
        name: A name for this dataloader source. If the instance is a module, the name corresponds to the hook
            that returns the desired dataloader(s).

    """

    instance: Optional[Union[TRAIN_DATALOADERS, EVAL_DATALOADERS, "pl.LightningModule", "pl.LightningDataModule"]]
    name: str

    def dataloader(self) -> Union[TRAIN_DATALOADERS, EVAL_DATALOADERS]:

Review comment (performance):
```suggestion
            dl = DataLoader(
                dataset=dl.dataset,
                batch_size=dl.batch_size,
                sampler=sampler,
                num_workers=dl.num_workers,
                collate_fn=dl.collate_fn,
                pin_memory=dl.pin_memory,
                drop_last=dl.drop_last,
                timeout=dl.timeout,
                worker_init_fn=dl.worker_init_fn,
                multiprocessing_context=dl.multiprocessing_context,
                generator=dl.generator,
                prefetch_factor=dl.prefetch_factor,
                persistent_workers=dl.persistent_workers,
            )
        updated.append(dl)
```

Code after:

    Arguments:
        instance: A LightningModule, LightningDataModule, or (a collection of) iterable(s).
        name: A name for this dataloader source. If the instance is a module, the name corresponds to the hook
            that returns the desired dataloader(s).

    """

    instance: Optional[Union[TRAIN_DATALOADERS, EVAL_DATALOADERS, "pl.LightningModule", "pl.LightningDataModule"]]
    name: str

    def dataloader(self) -> Union[TRAIN_DATALOADERS, EVAL_DATALOADERS]:
        """Returns the dataloader from the source.

        If the source is a module, the method with the corresponding :attr:`name` gets called.

        """
        if isinstance(self.instance, pl.LightningModule):
            return call._call_lightning_module_hook(self.instance.trainer, self.name, pl_module=self.instance)
        if isinstance(self.instance, pl.LightningDataModule):
            assert self.instance.trainer is not None
            return call._call_lightning_datamodule_hook(self.instance.trainer, self.name)
        assert self.instance is not None
        return self.instance

    def is_defined(self) -> bool:
        """Returns whether the source dataloader can be retrieved or not.

        If the source is a module it checks that the method with given :attr:`name` is overridden.

        """
        return not self.is_module() or is_overridden(self.name, self.instance)

    def is_module(self) -> bool:
        """Returns whether the DataLoader source is a LightningModule or a LightningDataModule.

        It does not check whether ``*_dataloader`` methods are actually overridden.

        """
        return isinstance(self.instance, (pl.LightningModule, pl.LightningDataModule))


def _request_dataloader(data_source: _DataLoaderSource) -> Union[TRAIN_DATALOADERS, EVAL_DATALOADERS]:
    """Requests a dataloader by calling dataloader hooks corresponding to the given stage.

    Returns:
        The requested dataloader

    """
    with _replace_dunder_methods(DataLoader, "dataset"), _replace_dunder_methods(BatchSampler):
        # under this context manager, the arguments passed to `DataLoader.__init__` will be captured and saved as