filter renameVars taking more then 50 seconds
Staying on theme #11174 I have stumbled upon a very slow case of renameVars coming from this file: https://github.com/PXshadow/filter_renameVars/blob/master/golibs/_internal/golangdotorg/x/text/unicode/norm/Norm__buildrecompmap.hx This file is mainly composed of transpiling this Go variable into Haxe code using go2hx: https://github.com/golang/text/blob/master/unicode/norm/tables10.0.0.go#L6715
name | time(s) | % | p% | # | info
---------------------------------------------------------------------------
generate | 68.647 | 46 | 46 | 3 |
hl | 68.647 | 46 | 100 | 3 |
opt | 56.910 | 38 | 83 | 1 |
write | 6.900 | 5 | 10 | 1 |
filters | 59.951 | 40 | 40 | 190816 |
RenameVars | 55.795 | 37 | 93 | 12533 |
_buildRecompMap | 51.651 | 34 | 93 | 1 | _internal.golangdotorg.x.text.unicode.norm._Norm__buildrecompmap.Norm__buildrecompmap_Fields_
_xorData | 2.690 | 2 | 5 | 1 | _internal.golangdotorg.x.net.idna._Idna__xordata.Idna__xordata_Fields_
_detailedPowersOfTen | 0.690 | 0 | 1 | 1 | stdgo._internal.strconv._Strconv__detailedpowersoften.Strconv__detailedpowersoften_Fields_
names | 0.104 | 0 | 0 | 1 | TypeInfoData_go2hx_
_rngCooked | 0.099 | 0 | 0 | 1 | stdgo._internal.math.rand._Rand__rngcooked.Rand__rngcooked_Fields_
reverse16 | 0.034 | 0 | 0 | 1 | stdgo._internal.math.bits._Bits_reverse16.Bits_reverse16_Fields_
__CaseRanges | 0.030 | 0 | 0 | 1 | stdgo._internal.unicode._Unicode___caseranges.Unicode___caseranges_Fields_
newEncoding | 0.021 | 0 | 0 | 1 | stdgo._internal.encoding.base64._Base64_newencoding.Base64_newencoding_Fields_
_sniffSignatures | 0.015 | 0 | 0 | 1 | stdgo._internal.net.http._Http__sniffsignatures.Http__sniffsignatures_Fields_
_nextHangul | 0.012 | 0 | 0 | 1 | _internal.golangdotorg.x.text.unicode.norm._Norm__nexthangul.Norm__nexthangul_Fields_
reverse8 | 0.010 | 0 | 0 | 1 | stdgo._internal.math.bits._Bits_reverse8.Bits_reverse8_Fields_
dce | 0.900 | 1 | 2 | 4 |
mark | 0.899 | 1 | 100 | 1 |
inline_constructors | 0.538 | 0 | 1 | 12533 |
names | 0.103 | 0 | 19 | 1 | TypeInfoData_go2hx_
_buildRecompMap | 0.063 | 0 | 12 | 1 | _internal.golangdotorg.x.text.unicode.norm._Norm__buildrecompmap.Norm__buildrecompmap_Fields_
_decomps | 0.054 | 0 | 10 | 1 | _internal.golangdotorg.x.text.unicode.norm._Norm__decomps.Norm__decomps_Fields_
_idnaSparseValues | 0.017 | 0 | 3 | 1 | _internal.golangdotorg.x.net.idna._Idna__idnasparsevalues.Idna__idnasparsevalues_Fields_
_idnaValues | 0.017 | 0 | 3 | 1 | _internal.golangdotorg.x.net.idna._Idna__idnavalues.Idna__idnavalues_Fields_
_detailedPowersOfTen | 0.011 | 0 | 2 | 1 | stdgo._internal.strconv._Strconv__detailedpowersoften.Strconv__detailedpowersoften_Fields_
sanitize | 0.405 | 0 | 1 | 12533 |
_buildRecompMap | 0.050 | 0 | 12 | 1 | _internal.golangdotorg.x.text.unicode.norm._Norm__buildrecompmap.Norm__buildrecompmap_Fields_
names | 0.036 | 0 | 9 | 1 | TypeInfoData_go2hx_
_idnaValues | 0.014 | 0 | 3 | 1 | _internal.golangdotorg.x.net.idna._Idna__idnavalues.Idna__idnavalues_Fields_
_xorData | 0.013 | 0 | 3 | 1 | _internal.golangdotorg.x.net.idna._Idna__xordata.Idna__xordata_Fields_
_nfkcValues | 0.011 | 0 | 3 | 1 | _internal.golangdotorg.x.text.unicode.norm._Norm__nfkcvalues.Norm__nfkcvalues_Fields_
_bidiValues | 0.011 | 0 | 3 | 1 | _internal.golangdotorg.x.text.unicode.bidi._Bidi__bidivalues.Bidi__bidivalues_Fields_
reduce_expression | 0.314 | 0 | 1 | 12533 |
names | 0.062 | 0 | 20 | 1 | TypeInfoData_go2hx_
_buildRecompMap | 0.050 | 0 | 16 | 1 | _internal.golangdotorg.x.text.unicode.norm._Norm__buildrecompmap.Norm__buildrecompmap_Fields_
_xorData | 0.020 | 0 | 6 | 1 | _internal.golangdotorg.x.net.idna._Idna__xordata.Idna__xordata_Fields_
_idnaValues | 0.012 | 0 | 4 | 1 | _internal.golangdotorg.x.net.idna._Idna__idnavalues.Idna__idnavalues_Fields_
handle_abstract_casts | 0.263 | 0 | 0 | 12533 |
_buildRecompMap | 0.036 | 0 | 14 | 1 | _internal.golangdotorg.x.text.unicode.norm._Norm__buildrecompmap.Norm__buildrecompmap_Fields_
names | 0.035 | 0 | 13 | 1 | TypeInfoData_go2hx_
fix_return_dynamic_from_void_function | 0.228 | 0 | 0 | 12533 |
_buildRecompMap | 0.039 | 0 | 17 | 1 | _internal.golangdotorg.x.text.unicode.norm._Norm__buildrecompmap.Norm__buildrecompmap_Fields_
names | 0.023 | 0 | 10 | 1 | TypeInfoData_go2hx_
_detailedPowersOfTen | 0.012 | 0 | 5 | 1 | stdgo._internal.strconv._Strconv__detailedpowersoften.Strconv__detailedpowersoften_Fields_
_xorData | 0.011 | 0 | 5 | 1 | _internal.golangdotorg.x.net.idna._Idna__xordata.Idna__xordata_Fields_
local_statics | 0.214 | 0 | 0 | 12533 |
_buildRecompMap | 0.035 | 0 | 16 | 1 | _internal.golangdotorg.x.text.unicode.norm._Norm__buildrecompmap.Norm__buildrecompmap_Fields_
names | 0.023 | 0 | 11 | 1 | TypeInfoData_go2hx_
new | 0.022 | 0 | 10 | 1 | stdgo._internal.net.http.T_stringWriter
_xorData | 0.011 | 0 | 5 | 1 | _internal.golangdotorg.x.net.idna._Idna__xordata.Idna__xordata_Fields_
mark_switch_break_loops | 0.202 | 0 | 0 | 12533 |
names | 0.038 | 0 | 19 | 1 | TypeInfoData_go2hx_
_buildRecompMap | 0.035 | 0 | 17 | 1 | _internal.golangdotorg.x.text.unicode.norm._Norm__buildrecompmap.Norm__buildrecompmap_Fields_
_appendFlush | 0.013 | 0 | 6 | 1 | _internal.golangdotorg.x.text.unicode.norm._Norm__appendflush.Norm__appendflush_Fields_
_xorData | 0.011 | 0 | 6 | 1 | _internal.golangdotorg.x.net.idna._Idna__xordata.Idna__xordata_Fields_
captured_vars | 0.166 | 0 | 0 | 12533 |
_buildRecompMap | 0.030 | 0 | 18 | 1 | _internal.golangdotorg.x.text.unicode.norm._Norm__buildrecompmap.Norm__buildrecompmap_Fields_
check_local_vars_init | 0.124 | 0 | 0 | 12533 |
_buildRecompMap | 0.014 | 0 | 11 | 1 | _internal.golangdotorg.x.text.unicode.norm._Norm__buildrecompmap.Norm__buildrecompmap_Fields_
Exceptions_filter | 0.086 | 0 | 0 | 12533 |
_buildRecompMap | 0.035 | 0 | 41 | 1 | _internal.golangdotorg.x.text.unicode.norm._Norm__buildrecompmap.Norm__buildrecompmap_Fields_
add_final_return | 0.083 | 0 | 0 | 12533 |
_insertUnsafe | 0.070 | 0 | 85 | 1 | _internal.golangdotorg.x.text.unicode.norm.T_reorderBuffer_static_extension
insert_save_stacks | 0.070 | 0 | 0 | 11974 |
check_abstract_as_value | 0.040 | 0 | 0 | 12533 |
Tre | 0.026 | 0 | 0 | 12533 |
string | 0.012 | 0 | 45 | 1 | stdgo._internal.flag.T_boolValue_asInterface
analyzer | 11.380 | 8 | 8 | 5702356 |
<- | 9.175 | 6 | 81 | 5641617 |
fusion | 8.545 | 6 | 93 | 5619297 |
fuse | 7.706 | 5 | 90 | 4928698 |
replace | 3.370 | 2 | 44 | 4470031 |
block_element | 0.337 | 0 | 4 | 668279 |
infer_from_texpr | 0.185 | 0 | 2 | 11160 |
to-texpr | 0.395 | 0 | 4 | 11160 |
cleanup | 0.236 | 0 | 3 | 11160 |
-> | 1.900 | 1 | 17 | 55800 |
from-texpr | 0.958 | 1 | 50 | 11160 |
idom | 0.537 | 0 | 28 | 11160 |
var writes | 0.200 | 0 | 11 | 11160 |
filter-apply | 0.178 | 0 | 9 | 11160 |
infer_scopes | 0.027 | 0 | 1 | 11160 |
other | 0.302 | 0 | 3 | 1 |
macro | 4.349 | 3 | 3 | 11694 |
jit | 0.022 | 0 | 1 | 3588 |
parsing | 3.520 | 2 | 2 | 4406 |
typing | 2.095 | 1 | 1 | 8582 |
finalize | 0.090 | 0 | 0 | 1 |
other | 0.064 | 0 | 0 | 0 |
---------------------------------------------------------------------------
total | 150.104 | 100 | 100 | 5917860 |
Ah yes, the old 7k function arguments trick, I wonder why that's so slow!
Note that stdgo.Go.str is a macro.
It ends up generating thousands of haxe.io.BytesBuffer.addByte calls so after inlining there's a lot of variables named this/pos which is presumably what makes renamevars so slow.
-D no-inline brings filter times down to 3 seconds.
Ah dammit, that means I can't just dismiss this as "crazy". At least not how I originally planned to!
I would completely understand if you did @Simn , but I am grateful for @Apprentice-Alchemist explanation.
Minimal example:
import haxe.io.BytesBuffer;
macro function makeMess() {
return macro $b{[for (i in 0...3000) macro b.addByte($v{i})]};
}
function main() {
#if !macro
var b = new BytesBuffer();
makeMess();
#end
}
While this generates some truly awful code, I'd still like to make sure that all our filtering algorithms run in linear-ish time.
I appreciate wanting to get the filtering algo to run in linear time-ish, also I'm happy for a better suggestion when it comes to the code generation, I likely missed something but I didn't know how else to create a sequence of literal bytes. (I need to do this because Go allows invalid byte sequences as a string, and Haxe does not)