this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

improve escaping performance

+63 -4
+6
CHANGELOG.md
··· 1 1 # CHANGELOG 2 2 3 + ## v1.2.0 - 2025/07/18 4 + 5 + - Improved performance of escaping on the Erlang target: escaping can now be up 6 + to x2.5 faster when escaping strings with little carachters to escape, and up 7 + to x1.3 faster when escaping strings with many characters to escape. 8 + 3 9 ## v1.1.0 - 2025/03/29 4 10 5 11 - Improve performance of escaping.
+57 -4
src/houdini/internal/escape_erl.gleam
··· 66 66 67 67 <<>> -> acc 68 68 69 - _ -> panic as "non byte aligned string, all strings should be byte aligned" 69 + _ -> 70 + panic as "do_escape: non byte aligned string, all strings should be byte aligned" 70 71 } 71 72 } 72 73 ··· 126 127 do_escape(rest, skip + len + 1, original, acc) 127 128 } 128 129 129 - // If a byte doesn't need escaping we keep increasing the length of the 130 - // slice we're going to take. 130 + // Otherwise we know that the first byte doesn't need any escape. The easy 131 + // thing to do would be to just advance by that one byte and keep going over 132 + // over the string. As you might notice here we're doing something a bit 133 + // more involved: we look at the following 7 bytes, and if none of those 134 + // needs escaping, then we skip this whole chunk of bytes entirely. 135 + // 136 + // This doesn't change the behaviour of the program, but it can make it a 137 + // whole load faster to go over the entire string. Especially if there's 138 + // fewer characters that need escaping! 139 + // 140 + // This idea comes from the amazing talk "Engineering json - Achieving Top 141 + // Performance on the BEAM" by Michał Muskala at Code BEAM Europe 2024: 142 + // https://www.youtube.com/watch?v=Z0swkSXAPBE 143 + <<_, b, c, d, e, f, g, h, rest:bits>> 144 + if b != 34 145 + && b != 38 146 + && b != 39 147 + && b != 60 148 + && b != 62 149 + && c != 34 150 + && c != 38 151 + && c != 39 152 + && c != 60 153 + && c != 62 154 + && d != 34 155 + && d != 38 156 + && d != 39 157 + && d != 60 158 + && d != 62 159 + && e != 34 160 + && e != 38 161 + && e != 39 162 + && e != 60 163 + && e != 62 164 + && f != 34 165 + && f != 38 166 + && f != 39 167 + && f != 60 168 + && f != 62 169 + && g != 34 170 + && g != 38 171 + && g != 39 172 + && g != 60 173 + && g != 62 174 + && h != 34 175 + && h != 38 176 + && h != 39 177 + && h != 60 178 + && h != 62 179 + -> do_escape_normal(rest, skip, original, acc, len + 8) 180 + 181 + // However, if any of the following bytes needs escaping, we skip over just 182 + // the first byte! 131 183 <<_, rest:bits>> -> do_escape_normal(rest, skip, original, acc, len + 1) 132 184 133 185 <<>> -> ··· 139 191 _ -> <<acc:bits, slice(original, skip, len):bits>> 140 192 } 141 193 142 - _ -> panic as "non byte aligned string, all strings should be byte aligned" 194 + _ -> 195 + panic as "do_escape_normal: non byte aligned string, all strings should be byte aligned" 143 196 } 144 197 } 145 198