|
1 | 1 | import { bench, describe } from 'vitest' |
2 | 2 |
|
| 3 | +const garbageFields = |
| 4 | + 'DUMMY1=value1;DUMMY2=value2;DUMMY3=value3;DUMMY4=value4;DUMMY5=value5;' + |
| 5 | + 'DUMMY6=value6;DUMMY7=value7;DUMMY8=value8;DUMMY9=value9;DUMMY10=value10;' + |
| 6 | + 'DUMMY11=value11;DUMMY12=value12;DUMMY13=value13;DUMMY14=value14;DUMMY15=value15;' + |
| 7 | + 'DUMMY16=value16;DUMMY17=value17;DUMMY18=value18;DUMMY19=value19;DUMMY20=value20;' + |
| 8 | + 'DUMMY21=value21;DUMMY22=value22;DUMMY23=value23;DUMMY24=value24;DUMMY25=value25;' + |
| 9 | + 'DUMMY26=value26;DUMMY27=value27;DUMMY28=value28;DUMMY29=value29;DUMMY30=value30;' + |
| 10 | + 'DUMMY31=value31;DUMMY32=value32;DUMMY33=value33;DUMMY34=value34;DUMMY35=value35;' + |
| 11 | + 'DUMMY36=value36;DUMMY37=value37;DUMMY38=value38;DUMMY39=value39;DUMMY40=value40' |
| 12 | + |
3 | 13 | const sampleInfoFields = [ |
4 | | - 'AC=1;AF=0.5;AN=2;DP=100;END=12345;MQ=60;NS=2', |
5 | | - 'SVTYPE=TRA;CHR2=chr2;END=54321;CT=3to5', |
6 | | - 'IMPRECISE;SVTYPE=DEL;END=10000;SVLEN=-500;CIPOS=-10,10', |
7 | | - 'END=5000;SVTYPE=INS;SVLEN=300;HOMLEN=10;HOMSEQ=ACGT', |
8 | | - 'DP=50;VDB=0.5;RPB=1.0;MQB=0.9;BQB=0.8;MQSB=0.85;SGB=-0.693147;MQ0F=0;END=8000', |
9 | | - 'SVTYPE=DUP;END=20000;SVLEN=1000;IMPRECISE;CIEND=-50,50', |
10 | | - 'AC=2;AF=1.0;AN=2;DP=200;END=15000;MQ=70;NS=3;DB', |
11 | | - 'INDEL;IDV=10;IMF=0.5;DP=100;VDB=0.8;RPB=0.9;END=7000', |
| 14 | + 'AC=1;AF=0.5;AN=2;DP=100;END=12345;MQ=60;NS=2;' + garbageFields, |
| 15 | + 'SVTYPE=TRA;CHR2=chr2;END=54321;CT=3to5;' + garbageFields, |
| 16 | + 'IMPRECISE;SVTYPE=DEL;END=10000;SVLEN=-500;CIPOS=-10,10;' + garbageFields, |
| 17 | + 'END=5000;SVTYPE=INS;SVLEN=300;HOMLEN=10;HOMSEQ=ACGT;' + garbageFields, |
| 18 | + 'DP=50;VDB=0.5;RPB=1.0;MQB=0.9;BQB=0.8;MQSB=0.85;SGB=-0.693147;MQ0F=0;END=8000;' + |
| 19 | + garbageFields, |
| 20 | + 'SVTYPE=DUP;END=20000;SVLEN=1000;IMPRECISE;CIEND=-50,50;' + garbageFields, |
| 21 | + 'AC=2;AF=1.0;AN=2;DP=200;END=15000;MQ=70;NS=3;DB;' + garbageFields, |
| 22 | + 'INDEL;IDV=10;IMF=0.5;DP=100;VDB=0.8;RPB=0.9;END=7000;' + garbageFields, |
12 | 23 | ] |
13 | 24 |
|
14 | 25 | describe('String comparison methods', () => { |
@@ -125,10 +136,64 @@ describe('String comparison methods', () => { |
125 | 136 | } |
126 | 137 | } |
127 | 138 | }) |
| 139 | + |
| 140 | + bench('using includes() then indexOf()', () => { |
| 141 | + for (const info of sampleInfoFields) { |
| 142 | + let endCoordinate = 0 |
| 143 | + if (info.includes(';END=') || info.startsWith('END=')) { |
| 144 | + let pos = info.indexOf(';END=') |
| 145 | + if (pos === -1 && info.startsWith('END=')) { |
| 146 | + const valueEnd = info.indexOf(';') |
| 147 | + endCoordinate = Number.parseInt( |
| 148 | + info.slice(4, valueEnd === -1 ? info.length : valueEnd), |
| 149 | + 10, |
| 150 | + ) |
| 151 | + } else if (pos !== -1) { |
| 152 | + pos += 1 |
| 153 | + let valueEnd = info.indexOf(';', pos + 4) |
| 154 | + if (valueEnd === -1) { |
| 155 | + valueEnd = info.length |
| 156 | + } |
| 157 | + endCoordinate = Number.parseInt(info.slice(pos + 4, valueEnd), 10) |
| 158 | + } |
| 159 | + } |
| 160 | + if (endCoordinate) { |
| 161 | + // do something |
| 162 | + } |
| 163 | + } |
| 164 | + }) |
| 165 | + |
| 166 | + bench('using regex (cached)', () => { |
| 167 | + const endRegex = /(?:^|;)END=([^;]+)/ |
| 168 | + for (const info of sampleInfoFields) { |
| 169 | + let endCoordinate = 0 |
| 170 | + const match = endRegex.exec(info) |
| 171 | + if (match) { |
| 172 | + endCoordinate = Number.parseInt(match[1], 10) |
| 173 | + } |
| 174 | + if (endCoordinate) { |
| 175 | + // do something |
| 176 | + } |
| 177 | + } |
| 178 | + }) |
| 179 | + |
| 180 | + bench('using regex (created each iteration)', () => { |
| 181 | + for (const info of sampleInfoFields) { |
| 182 | + let endCoordinate = 0 |
| 183 | + const endRegex = /(?:^|;)END=([^;]+)/ |
| 184 | + const match = endRegex.exec(info) |
| 185 | + if (match) { |
| 186 | + endCoordinate = Number.parseInt(match[1], 10) |
| 187 | + } |
| 188 | + if (endCoordinate) { |
| 189 | + // do something |
| 190 | + } |
| 191 | + } |
| 192 | + }) |
128 | 193 | }) |
129 | 194 |
|
130 | 195 | describe('Combined scenario (realistic _getVcfEnd)', () => { |
131 | | - bench('original approach with includes + slice', () => { |
| 196 | + bench('includes for TRA + manual loop with slice', () => { |
132 | 197 | for (const info of sampleInfoFields) { |
133 | 198 | const startCoordinate = 1000 |
134 | 199 | const refSeq = 'ACGT' |
@@ -157,7 +222,7 @@ describe('String comparison methods', () => { |
157 | 222 | } |
158 | 223 | }) |
159 | 224 |
|
160 | | - bench('current approach with includes + character comparison', () => { |
| 225 | + bench('includes for TRA + manual loop with char-by-char', () => { |
161 | 226 | for (const info of sampleInfoFields) { |
162 | 227 | const startCoordinate = 1000 |
163 | 228 | const refSeq = 'ACGT' |
@@ -192,7 +257,7 @@ describe('String comparison methods', () => { |
192 | 257 | } |
193 | 258 | }) |
194 | 259 |
|
195 | | - bench('using includes + indexOf', () => { |
| 260 | + bench('includes for TRA + indexOf for END', () => { |
196 | 261 | for (const info of sampleInfoFields) { |
197 | 262 | const startCoordinate = 1000 |
198 | 263 | const refSeq = 'ACGT' |
@@ -223,5 +288,83 @@ describe('String comparison methods', () => { |
223 | 288 | } |
224 | 289 | } |
225 | 290 | }) |
| 291 | + |
| 292 | + bench('includes for TRA + includes guard + indexOf for END', () => { |
| 293 | + for (const info of sampleInfoFields) { |
| 294 | + const startCoordinate = 1000 |
| 295 | + const refSeq = 'ACGT' |
| 296 | + let endCoordinate = startCoordinate + refSeq.length |
| 297 | + |
| 298 | + const isTRA = info.includes('SVTYPE=TRA') |
| 299 | + if (info[0] !== '.' && !isTRA) { |
| 300 | + if (info.includes(';END=') || info.startsWith('END=')) { |
| 301 | + let pos = info.indexOf(';END=') |
| 302 | + if (pos === -1 && info.startsWith('END=')) { |
| 303 | + const valueEnd = info.indexOf(';') |
| 304 | + endCoordinate = Number.parseInt( |
| 305 | + info.slice(4, valueEnd === -1 ? info.length : valueEnd), |
| 306 | + 10, |
| 307 | + ) |
| 308 | + } else if (pos !== -1) { |
| 309 | + pos += 1 |
| 310 | + let valueEnd = info.indexOf(';', pos + 4) |
| 311 | + if (valueEnd === -1) { |
| 312 | + valueEnd = info.length |
| 313 | + } |
| 314 | + endCoordinate = Number.parseInt(info.slice(pos + 4, valueEnd), 10) |
| 315 | + } |
| 316 | + } |
| 317 | + } else if (isTRA) { |
| 318 | + endCoordinate = startCoordinate + 1 |
| 319 | + } |
| 320 | + if (endCoordinate) { |
| 321 | + // do something |
| 322 | + } |
| 323 | + } |
| 324 | + }) |
| 325 | + |
| 326 | + bench('includes for TRA + regex for END (cached)', () => { |
| 327 | + const endRegex = /(?:^|;)END=([^;]+)/ |
| 328 | + for (const info of sampleInfoFields) { |
| 329 | + const startCoordinate = 1000 |
| 330 | + const refSeq = 'ACGT' |
| 331 | + let endCoordinate = startCoordinate + refSeq.length |
| 332 | + |
| 333 | + const isTRA = info.includes('SVTYPE=TRA') |
| 334 | + if (info[0] !== '.' && !isTRA) { |
| 335 | + const match = endRegex.exec(info) |
| 336 | + if (match) { |
| 337 | + endCoordinate = Number.parseInt(match[1], 10) |
| 338 | + } |
| 339 | + } else if (isTRA) { |
| 340 | + endCoordinate = startCoordinate + 1 |
| 341 | + } |
| 342 | + if (endCoordinate) { |
| 343 | + // do something |
| 344 | + } |
| 345 | + } |
| 346 | + }) |
| 347 | + |
| 348 | + bench('includes for TRA + regex for END (created each iteration)', () => { |
| 349 | + for (const info of sampleInfoFields) { |
| 350 | + const startCoordinate = 1000 |
| 351 | + const refSeq = 'ACGT' |
| 352 | + let endCoordinate = startCoordinate + refSeq.length |
| 353 | + |
| 354 | + const isTRA = info.includes('SVTYPE=TRA') |
| 355 | + if (info[0] !== '.' && !isTRA) { |
| 356 | + const endRegex = /(?:^|;)END=([^;]+)/ |
| 357 | + const match = endRegex.exec(info) |
| 358 | + if (match) { |
| 359 | + endCoordinate = Number.parseInt(match[1], 10) |
| 360 | + } |
| 361 | + } else if (isTRA) { |
| 362 | + endCoordinate = startCoordinate + 1 |
| 363 | + } |
| 364 | + if (endCoordinate) { |
| 365 | + // do something |
| 366 | + } |
| 367 | + } |
| 368 | + }) |
226 | 369 | }) |
227 | 370 | }) |
0 commit comments