Oh, and if you did want to use a zero copy IO interface like `memfiles` on this, you can and indeed it is over 3X faster, but you have to write your own integer parser because `parseUint` and all its analogues take a Nim `string` not `MemSlice`. You can use the dollar operator `$` to convert, but that is no faster than just using `lines` in the first place. Parsing an integer in ASCII is actually pretty easy, though. E.g., import tables, os, memfiles proc parseUInt(data: cstring, size: int): uint {.inline.} = let zero = ord('0') let nine = ord('9') for i in 0 ..< size: let code = ord(data[i]) if code >= zero and code <= nine: result *= 10 result += uint(code - zero) else: return 0 #non-digit; parse error proc ytz(path: string): uint = var table = initTable[uint, uint]() mf = memfiles.open(path) if mf.mem == nil: quit("Cannot open " & path) for s in memSlices(mf): let n = parseUInt(cast[cstring](s.data), s.size) if n == 0: quit("Parse error: " & $s) table.mgetOrPut(n, 0) += n for key, val in table: result = max(result, val) mf.close proc main() = echo ytz(paramStr(1)) main() Run
Not a big deal here, but if the file were really large that factor of 3 might be more appreciated.