My 1billion row challenge solutions in various languages
at main 2.8 kB view raw
1import 'dart:collection'; 2import 'dart:convert'; 3import 'dart:io'; 4import 'dart:isolate'; 5 6final newLine = 10; 7final semiColon = 59; 8final minus = 45; 9 10class Result { 11 double total = 0; 12 double? min = null; 13 double? max = null; 14 double count = 0; 15 16 void incrementCount() { 17 this.count += 1; 18 } 19 20 void addToTotal(double value) { 21 this.total += value; 22 } 23 24 void processMin(double value) { 25 if (this.min == null || this.min! > value) { 26 this.min = value; 27 } 28 } 29 30 void processMax(double value) { 31 if (this.max == null || this.max! < value) { 32 this.max = value; 33 } 34 } 35 36 double avg() { 37 return (this.total / this.count); 38 } 39} 40 41final Map<String, Result> res = 42 SplayTreeMap<String, Result>((a, b) => a.compareTo(b)); 43 44void main() async { 45 final file = File('measurements.txt').openSync(); 46 final fileSize = file.lengthSync(); 47 final maxLineLength = 106; 48 49 final threadCount = Platform.numberOfProcessors; 50 51 final chunkSize = fileSize ~/ threadCount; 52 final offsets = <int>[]; 53 54 int offset = 0; 55 for (int i = 0; i < threadCount; i++) { 56 offsets.add(offset); 57 58 offset += chunkSize; 59 60 if (offset >= fileSize) { 61 break; 62 } 63 file.setPositionSync(offset); 64 var line = file.readSync(maxLineLength); 65 66 offset += line.indexOf(newLine) + 1; 67 } 68 final processor = 69 List<Future<Map<String, Result>>>.generate(offsets.length, (int i) { 70 var end = offsets.length == i + 1 ? fileSize : offsets[i + 1]; 71 return Isolate.run(() => processChunk(offsets[i], end)); 72 }); 73 for (var res in await Future.wait(processor)) { 74 addResults(res); 75 } 76 77 printResults(); 78} 79 80void addResults(Map<String, Result> results) { 81 results.forEach((key, val) { 82 res.putIfAbsent(key, () => new Result()) 83 ..addToTotal(val.total) 84 ..processMin(val.min!) 85 ..processMax(val.max!) 86 ..count += val.count; 87 }); 88} 89 90Future<Map<String, Result>> processChunk(int start, int end) async { 91 final res = new HashMap<String, Result>(); 92 final file = File("measurements.txt"); 93 List<int> buffer = List<int>.filled(106, 0); 94 String line = ''; 95 int ct = 0; 96 List<String> split; 97 await for (var chunk in file.openRead(start, end)) { 98 for (var b in chunk) { 99 if (b != newLine) { 100 buffer[ct] = b; 101 ct++; 102 } else { 103 line = utf8.decode(buffer.take(ct).toList()); 104 split = line.split(';'); 105 var value = double.parse(split[1]); 106 res.putIfAbsent(split[0], () => new Result()) 107 ..addToTotal(value!) 108 ..processMin(value) 109 ..processMax(value) 110 ..incrementCount(); 111 ct = 0; 112 } 113 } 114 } 115 return res; 116} 117 118void printResults() { 119 res.forEach((key, value) { 120 print('$key;${value.min};${value.avg().toStringAsFixed(1)};${value.max}'); 121 }); 122}