Package: MSnbase
Authors: Laurent Gatto and Johannes Rainer
Modified: NA
Compiled: Wed Jan 04 19:08:09 2017
In this vignette, we will document various timings and benchmarkings of the recent MSnbase development (aka MSnbase2
), that focuses on on-disk data access (as opposed to in-memory). More details about the new implementation will be documented elsewhere.
As a benchmarking dataset, we are going to use a subset of an TMT 6-plex experiment acquired on an LTQ Orbitrap Velos, that is distributed with the msdata package
library("msdata")
f <- msdata::proteomics(full.names = TRUE, pattern = "TMT_Erwinia")
basename(f)
## [1] "TMT_Erwinia_1uLSike_Top10HCD_isol2_45stepped_60min_01.mzML.gz"
We need to load the MSnbase package and set the session-wide verbosity flag to FALSE
.
library("MSnbase")
setMSnbaseVerbose(FALSE)
We first read the data using the original readMSData
function that generates an in-memory representation of the MS2-level raw data and measure the time needed for this operation.
system.time(inmem <- readMSData(f, msLevel = 2,
centroided = TRUE))
## user system elapsed
## 11.61 0.11 12.77
Next, we use the readMSData2
function to generate an on-disk representation of the same data.
system.time(ondisk <- readMSData2(f, msLevel = 2,
centroided = TRUE))
## user system elapsed
## 1.80 0.08 2.00
Creating the on-disk experiment is considerable faster and scales to much bigger, multi-file data, both in terms of object creation time, but also in terms of object size (see next section). We must of course make sure that these two datasets are equivalent:
all.equal(inmem, ondisk)
## [1] TRUE
To compare the size occupied in memory of these two objects, we are going to use the object_size
function from the pryr package, which accounts for the data (the spectra) in the assayData
environment (as opposed to the object.size
function from the utils
package).
library("pryr")
object_size(inmem)
## 2.68 MB
object_size(ondisk)
## 115 kB
The difference is explained by the fact that for ondisk
, the spectra are not created and stored in memory; they are access on disk when needed, such as for example for plotting:
plot(inmem[[200]], full = TRUE)
plot(ondisk[[200]], full = TRUE)
Figure 1: Plotting in-memory and on-disk spectra
The drawback of the on-disk representation is when the spectrum data has to actually be accessed. To compare access time, we are going to use the microbenchmark and repeat access 10 times to compare access to all 451 and a single spectrum in-memory (i.e. pre-loaded and constructed) and on-disk (i.e. on-the-fly access).
library("microbenchmark")
mb <- microbenchmark(spectra(inmem),
inmem[[200]],
spectra(ondisk),
ondisk[[200]],
times = 10)
mb
## Unit: microseconds
## expr min lq mean median
## spectra(inmem) 137.119 213.153 256.5950 231.9480
## inmem[[200]] 53.822 87.995 103.5437 96.5385
## spectra(ondisk) 1577401.184 1600994.087 1819302.5074 1669543.2335
## ondisk[[200]] 552788.651 598798.485 710468.2401 676850.8735
## uq max neval cld
## 304.138 431.859 10 a
## 106.790 157.195 10 a
## 2170828.985 2270449.112 10 c
## 815694.116 880959.042 10 b
While it takes order or magnitudes more time to access the data on-the-fly rather than a pre-generated spectrum, accessing all spectra is only marginally slower than accessing all spectra, as most of the time is spent preparing the file for access, which is done only once.
On-disk access performance will depend on the read throughput of the disk. A comparison of the data import of the above file from an internal solid state drive and from an USB3 connected hard disk showed only small differences for the readMSData2
call (1.07 vs 1.36 seconds), while no difference were observed for accessing individual or all spectra. Thus, for this particular setup, performance was about the same for SSD and HDD. This might however not apply to setting in which data import is performed in parallel from multiple files.
Data access does not prohibit interactive usage, such as plotting, for example, as it is about 1/2 seconds, which is an operation that is relatively rare, compared to subsetting and filtering, which are faster for on-disk data:
i <- sample(length(inmem), 100)
system.time(inmem[i])
## user system elapsed
## 0.33 0.04 0.35
system.time(ondisk[i])
## user system elapsed
## 0.09 0.00 0.09
Operations on the spectra data, such as peak picking, smoothing, cleaning, … are cleverly cached and only applied when the data is accessed, to minimise file access overhead. Finally, specific operations such as for example quantitation (see next section) are optimised for speed.
Below, we perform TMT 6-plex reporter ions quantitation on the first 100 spectra and verify that the results are identical (ignoring feature names).
system.time(eim <- quantify(inmem[1:100], reporters = TMT6,
method = "max"))
## user system elapsed
## 0.41 0.01 11.69
system.time(eod <- quantify(ondisk[1:100], reporters = TMT6,
method = "max"))
## user system elapsed
## 0.7 0.1 0.8
all.equal(eim, eod, check.attributes = FALSE)
## [1] TRUE
This document focuses on speed and size improvements of the new on-disk MSnExp
representation. The extend of these improvements will substantially increase for larger data.
For general functionality about the on-disk MSnExp
data class and MSnbase in general, see other vignettes available with
vignette(package = "MSnbase")