haxetink / tink_web

Tinkerbell Web Framework
https://haxetink.github.io/tink_web
43 stars 14 forks source link

Compilation time for routes with complex body definitions is non-linear #120

Closed hypersurge closed 3 years ago

hypersurge commented 3 years ago

Compilation time (observed on JS and PHP) takes a big hit when creating a route with a body with many members (30 seconds or more for 50 members).

Here's a minimal example:

import tink.http.containers.*;
import tink.http.Response;
import tink.web.routing.*;

class Main
{
    static function main()
    {
        var l_container = PhpContainer.inst;
        var l_router = new Router<Root>( new Root() );
        l_container.run( p_request -> l_router.route( Context.ofRequest( p_request ) ).recover( OutgoingResponse.reportError ) );
    }
}

class Root
{
    public function new()
    {
    }    

    @:get( 'test' )
    @:produces( 'text/html' )
    public function getTest( body:
        {
            ?a1:String, ?a2:String, ?a3:String, ?a4:String, ?a5:String, ?a6:String, ?a7:String, ?a8:String, ?a9:String, ?a10:String,
            ?b1:String, ?b2:String, ?b3:String, ?b4:String, ?b5:String, ?b6:String, ?b7:String, ?b8:String, ?b9:String, ?b10:String,
            ?c1:String, ?c2:String, ?c3:String, ?c4:String, ?c5:String, ?c6:String, ?c7:String, ?c8:String, ?c9:String, ?c10:String,
            ?d1:String, ?d2:String, ?d3:String, ?d4:String, ?d5:String, ?d6:String, ?d7:String, ?d8:String, ?d9:String, ?d10:String,
            ?e1:String, ?e2:String, ?e3:String, ?e4:String, ?e5:String, ?e6:String, ?e7:String, ?e8:String, ?e9:String, ?e10:String,
        } 
        )
    {
        return "OK";
    }
}

Comment out all the "e"s and compile time is ~halved, comment out the "d"s and compile time is ~halved again, comment out the "c"s and compile time is negligible.

@back2dos described this on Gitter as "seems like the macro has non-linear complexity"

hypersurge commented 3 years ago

For others encountering this issue ... you may find an immediate workaround is to reduce the total number of unique body parameters (e.g. by using arrays or more complex objects).

kevinresol commented 3 years ago

Perhaps the non linear complexity comes from the conflict checker https://github.com/haxetink/tink_web/blob/3b2d1560c91966ce6b72aeb98d3aa6235e2eb183/src/tink/web/macros/Parameters.hx#L78-L106

back2dos commented 3 years ago

Ok, looks like the macro isn't the problem (I rewrote it with maps to avoid the double loop to no effect). Compiling with -D times gives me filters | 27.283 | 77 | 77 | 11 |, so something's wrong there. Tried to upgrade to nightly, but got stuck on some final variance issue. Will check later.

back2dos commented 3 years ago

Looking at the generated code, it seems like we're generating a variable called body 2500 times (there's 50 fields and 50 * 50 happens to be 2500).