| Literature DB >> 31159721 |
Pascal Costanza1, Charlotte Herzeel1, Wilfried Verachtert1.
Abstract
BACKGROUND: elPrep is an established multi-threaded framework for preparing SAM and BAM files in sequencing pipelines. To achieve good performance, its software architecture makes only a single pass through a SAM/BAM file for multiple preparation steps, and keeps sequencing data as much as possible in main memory. Similar to other SAM/BAM tools, management of heap memory is a complex task in elPrep, and it became a serious productivity bottleneck in its original implementation language during recent further development of elPrep. We therefore investigated three alternative programming languages: Go and Java using a concurrent, parallel garbage collector on the one hand, and C++17 using reference counting on the other hand for handling large amounts of heap objects. We reimplemented elPrep in all three languages and benchmarked their runtime performance and memory use.Entities:
Keywords: C++; Garbage collection; Go; Java; Memory usage; Next-generation sequencing; Reference counting; Runtime performance; SAM/BAM files; Sequence analysis
Mesh:
Year: 2019 PMID: 31159721 PMCID: PMC6547519 DOI: 10.1186/s12859-019-2903-5
Source DB: PubMed Journal: BMC Bioinformatics ISSN: 1471-2105 Impact factor: 3.169
Fig. 1Runtime performance. Average elapsed wall-clock times in minutes for the best Go, Java, and C++17 implementations, with confidence intervals
Fig. 2Maximum memory use. Average maximum memory use in GB for the best Go, Java, and C++17 implementations, with confidence intervals
Fig. 3Final ranking of programming languages. Average elapsed wall-clock times multiplied by average maximum memory use in GBh
Fig. 4Runtimes of phases in the C++17 implementation. Average elapsed wall-clock times in minutes for the two main phases of an elPrep pipeline in the C++17 implementation, and the deallocation pause in between phase 1 and 2 caused by the reference counting mechanism, with confidence intervals. The second row depicts the same averages as in the first now, but without the deallocation pause. The sum of the two phases in the second row is very close to the Go runtimes shown in Fig. 1
Performance results for the different memory allocators used in the C++17 benchmarks: (1) default allocator, (2) tbbmalloc, (3) tcmalloc, (4) jemalloc
| Average runtime | Average memory | Product | |
|---|---|---|---|
| (1) | 16 mins 57.467 secs | 233.63 GB | 66.03 GBh |
| (2) | 16 mins 26.450 secs | 233.51 GB | 63.96 GBh |
| (3) | 11 mins 24.809 secs | 246.78 GB | 46.94 GBh |
| (4) | 10 mins 23.603 secs | 255.48 GB | 44.26 GBh |
Performance results for the different memory management options used in the Java benchmarks: (1) default options, (2) with string deduplication, (3) with heap-free options, (4) with string deduplication and heap-free options
| Average runtime | Average memory | Product | |
|---|---|---|---|
| (1) | 6 mins 54.546 secs | 335.46 GB | 38.63 GBh |
| (2) | 7 mins 30.815 secs | 338.74 GB | 42.42 GBh |
| (3) | 6 mins 55.842 secs | 335.45 GB | 38.75 GBh |
| (4) | 7 mins 25.415 secs | 338.74 GB | 41.91 GBh |