Optimise Recfile output generation
John Smith

John Smith commited on 2022-214 13:37:56
Showing 1 changed files, with 12 additions and 6 deletions.


The Recfile-save function was painfully slow, perhaps accidentally
quadratic, due to inefficiencies in string concatenation.
Replacing a loop with a binary-tree recursion speeds it up greatly --
on my deck, the Recfile generation step now runs >18x faster.
... ...
@@ -83,18 +83,24 @@ end
83 83
     returns (on success) a string
84 84
     returns (on failure) nil
85 85
 ]]
86
-local function recs2text(recs)
86
+local function recs2text(recs, si, ei)
87 87
     local ret = ""
88
-    -- go through records
89
-    for i, rec in ipairs(recs) do
90
-        for label, vl in pairs(rec) do
88
+    si = si or 1
89
+    ei = ei or #recs
90
+    --[[
91
+        use recursive (binary-splitting) string building
92
+        this makes stuff way more efficient
93
+    ]]
94
+    if si == ei then
95
+        for label, vl in pairs(recs[si]) do
91 96
             for j, value in ipairs(vl) do
92 97
                 ret = ret .. string.format("\n%s: %s", label, tostring(value):gsub("\n", "\n+ "))
93 98
             end
94 99
         end
95
-        ret = ret .. "\n"
100
+        return ret .. "\n"
101
+    else
102
+        return recs2text(recs, si, (si + ei) // 2) .. recs2text(recs, (si + ei) // 2 + 1, ei)
96 103
     end
97
-    return ret
98 104
 end
99 105
 
100 106
 return { read = text2recs, write = recs2text }
101 107