Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JIT has become slower #149

Open
michael-e opened this issue Aug 13, 2016 · 11 comments
Open

JIT has become slower #149

michael-e opened this issue Aug 13, 2016 · 11 comments

Comments

@michael-e
Copy link
Member

According to my tests, JIT has become 23 percent slower in delivering cached files, comparing version 1.43 to the current integration branch (2.x).

I guess the reason is the "full-blown Symphony launch" that is done with every request nowadays?

If that is the case, and given the fact that performance has been a big target in the last weeks, I suggest to re-consider launching a complete Symphony instance.

Imagine, each time a visitor wants to see a page, you now launch:

  • 1 Symphony instance to generate the page
  • x Symphony instances in order to generate x images (or simply read them from cache)

I always considered JIT a "small but powerful work horse". Ideally, shouldn't it run without Symphony?

@michael-e
Copy link
Member Author

I should add that the server that used for these tests is blazingly fast in launching PHP scripts. It has a very big filesystem cache (in RAM), and it also uses Zend Opcache.

This means that the difference may even be bigger on most machines.

@michael-e
Copy link
Member Author

michael-e commented Aug 13, 2016

My first test wasn't really good, because I used an external file for testing. Using a local file, results are much worse. JIT has become more than 110 percent slower, in other words: It needs more than double the time to deliver a cached file.

BTW, I have used Apache's mod_headers to test this. It allows to set a custom header with special variables that will be evaluated.

%D: The time from when the request was received to the time the headers are sent on the wire. This is a measure of the duration of the request. The value is preceded by D=. The value is measured in microseconds.

On my (as I said, really fast) server the average values were:

  • for JIT 1.43: 3985 microseconds
  • for JIT 2.x: 8553 microseconds

With a lots of images on your page, this can sum up to a significant increase in processing time. The actual response time, of course, will depend on the number of (idle) processor cores (and Apache processes, and the filesystem, etc. etc.)

@michael-e
Copy link
Member Author

WTF! I have seen that even JIT 1.43 uses the autoloader as well, so it's probably not the "size of the Symphony object" that makes the difference. But what can it be? The dedicated "launcher"?

@nitriques
Copy link
Member

Wow. I really need to dig in more. In my tests, on a crappy server, performance was better when serving cache from disk. The dedicated launcher is a good idea and should not create a drastic performance loss: it did remove lots of code duplication and potential security holes...

@nitriques
Copy link
Member

Ah I just spotted it. It's the database. On my server, it's fast but the drives are really slow... We must find a solution...

@brendo
Copy link
Member

brendo commented Aug 15, 2016

So I never actually finished 2.0 and was kinda surprised that it was released when it was, and as such the actual caching check was never finished :)

You see inspecting the orchestration of this function that if caching was implemented a significant amount of work would be avoided.

Even if this was done though, I do anticipate there will be a small perf loss compared to v1.

Edit Sorry, didn't realise how far integration has come. There's definitely a lot more going on now =/

@michael-e
Copy link
Member Author

@nitriques:

Ah I just spotted it. It's the database.

JIT doesn't touch the database, does it?

@nitriques
Copy link
Member

nitriques commented Aug 16, 2016

@brendo Next time, please do it in a 'experimental' branch. I had to fix bugs, that is why I went into integration to try and fix them ;) But yeah, I am the one to blame. Sorry.

That being said, going the launcher route is the way to go IMHO. We just need to polish the rough edges.

@michael-e Yes it does. It has to run all this code before launching and loading extensions requires a database call.

I am currently looking on way to avoid this. With a proper DI system, I would be easier. But I have a couple of ideas on how to do it. Suggestions are always welcome.

@nitriques
Copy link
Member

nitriques commented Aug 16, 2016

After some tests on my crappy server... With a local cache everytime, I get a 10ms boost when not hitting the database. (54ms vs 44ms) (I've took my timing with @michael-e %D trick. I would have to compare to 1.43... but time to go to sleep.

This is my test bundle.php

<?php

    /**
     * @package boot
     */

    // Set appropriate error reporting:
    error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT);

    // Turn off old-style magic:
    ini_set('magic_quotes_runtime', false);

    // Redirect to installer if it exists
    if (!file_exists(CONFIG)) {
        die('<h2>Error</h2><p>Could not locate Symphony configuration file. Please check <code>manifest/config.php</code> exists.</p>');
    }
    // Load configuration file:
    include CONFIG;
    Symphony::initialiseConfiguration($settings);
    Symphony::initialiseErrorHandler();

    require_once __DIR__ . '/../lib/class.jit.php';
    JIT\JIT::instance()->display();

@michael-e
Copy link
Member Author

If you push to a dedicated (experimental) branch, I will test on my machine!

@brendo
Copy link
Member

brendo commented Aug 16, 2016

An idea @nitriques, most of the initialisation logic in the Symphony class is done ahead of time so that when Database(), Session() etc. are called, the code simply returns the appropriate instance.

What would be interesting is changing this logic so the simple accessors actually implemented initialising the objects "just in time" before returning the instance. In theory, this would speed up the entire application because if parts of the system aren't used, no extra cycles were spent setting it up.

Historically Lang() and Session has been expensive, so avoiding those for JIT would likely save some cycles.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants