Mailing List Articles Atom Feed Comments Atom Feed Twitter Reddit Facebook

Tag Cloud

3d account algorithms android announcement architecture archives arduino artificial intelligence artix assembly async audio bash batch blog bookmarklet booting c sharp c++ challenge chrome os code codepen coding conundrums coding conundrums evolved command line compilers compiling compression css dailyprogrammer debugging demystification distributed computing documentation downtime electronics email embedded systems encryption es6 features event experiment external first impressions future game github github gist graphics hardware hardware meetup holiday holidays html html5 html5 canvas infrastructure interfaces internet io.js jabber javascript js bin labs learning library linux low level lua maintenance manjaro network networking node.js operating systems performance photos php pixelbot portable privacy programming problems project projects prolog protocol protocols pseudo 3d python reddit reference release releases resource review rust secrets security series list server software sorting source code control statistics storage svg technical terminal textures three thing game three.js tool tutorial tutorials twitter ubuntu university update updates upgrade version control virtual reality virtualisation visual web website windows windows 10 xmpp xslt

How to prevent php-fpm from overriding your PHP-based caching logic

A while ago I implemented ETag support to the dynamic preview generator in Pepperminty Wiki. While I thought it worked during testing, for some reason on a private instance of Pepperminty Wiki I discovered recently that my browser didn't seen to be taking advantage of it. This got me curious, so I decided to do a little bit of digging to find out why.

It didn't take long to find the problem. For some reason, all the responses from the server had a Cache-Control: no-cache, no-store, must-revalidate header attached to them. How strange! Even more so that it was in capital letters - my convention in Pepperminty Wiki is to always make the headers lowercase.

I checked the codebase with via the Project Find feature of Atom just to make sure that I hadn't left in a debugging statement or anything (I hadn't), and then I turned my attention to Nginx (engine-x) - the web server that I use on my server. Maybe it had added a caching header?

A quick grep later revealed that it wasn't responsible either - which leaves just one part of the system unchecked - php-fpm, the PHP FastCGI server that sits just behind Nginx that's responsible for running the various PHP scripts I have that power this website and other corners of my server. Another quick grep returned a whole bunch of garbage, so after doing some research I discovered that php-fpm, by default, is configured to send this header - and that it has to be disabled by editing your php.ini (for me it's in /etc/php/7.1/fpm/php.ini), and changing

;session.cache_limiter = nocache

to be explicitly set to an empty string, like so:

session.cache_limiter = ''

This appears to have solved by problem for now - allowing me to regain control over how the resources I send back via PHP are cached. Hopefully this saves someone else the hassle of pulling their entire web server stack apart and putting it back together again the future :P

Found this helpful? Still having issues? Got a better way of solving the problem? Post a comment below!

C Sharp Performance Tests: Squaring Numbers

The semester 2 coursework has begun, and this time there is a choice of either make a game to a specification, or produce a business related application to a specification. I have chosen the game.

To start off, I started writing a few mathematical functions that I would need when ewriting the game itself. I quickly found that one of things you do rather a lot is squaring numbers. In C♯ I have found 2 ways to square a number so far: a*a and Math.Pow(a, 2), where a is a number.

Even though it probably doesn't matter about the speed at which we square numbers (there are much better optimisations to make), I decided to test it anyway. I wrote this program:

using System;
using System.Diagnostics;

class Program
    static void Main(string[] args)
        Console.WriteLine("This program tests the performance of squaring numbers.\n");
        Console.WriteLine("Iterations | a*a Time | Math.Pow(a, 2) Time");

        int iterations = 100000;
        double number = 3092d;
        double result;

            Stopwatch timera = Stopwatch.StartNew();

            for(int i = 0; i < iterations; i++)
                result = number*number;

            Stopwatch timerb = Stopwatch.StartNew();
            for(int i = 0; i < iterations; i++)
                result = Math.Pow(number, 2);

            Console.WriteLine(" {0,9} | {1,8} | {2}", iterations, timera.ElapsedMilliseconds.ToString(), timerb.ElapsedMilliseconds.ToString());

            iterations += 100000;

            System.Threading.Thread.Sleep(500); // make sure that we don't crash the server

(pastebin, binary)

I didn't have a Windows Machine handy when writing this post, so the binary has been compiled with mono's dcms. Please leave a comment below if it doesn't work for you.

Everything is done with doubles to maek it a fair test because C♯'s Math.Pow method will only accept a double. The code sleeps for half a second between runs because I was writing this on the server that is serving the websitee, and I didn't want to crash it by accident :)

The results were rather shocking. The easiest way to display the results is in a graph:

A graph of the results.

A pastebin of the results can be found here.

As you can quite clearly see, Math.Pow() is horribly inefficient compared to just multiplying a number by itself. Next time I am squaring numbers, I won't be using Math.Pow again.

Value vs Reference: A Performance Test

I have recently started to learned about classes and objects in C♯. In one of my lectures, Rob Miles mentioned that passing by reference introduced a slight performance hit, and I decided to test this.

Here is the code I used:

using System;
using System.Diagnostics;

class ValueVsReference
    public static void SetValue(int somenumber, int maxi)
        for (int i = 0; i < maxi; i++)
            somenumber = i;

    public static void SetReference(ref int somenumber, int maxi)
        for(int i = 0; i < maxi; i++)
            somenumber = i;

    public static void Main()
        int iterations = 100000;
        int a = 0;
        Console.Write("Iterations: {0} ", iterations);

        Console.Write("Value: ");
        Stopwatch valuetime = new Stopwatch();
        SetValue(a, iterations);
        Console.Write("{0} ", valuetime.Elapsed);

        Console.Write("Reference: ");
        Stopwatch referencetime = new Stopwatch();
        SetReference(ref a, iterations);


The results for 10,000 iterations can be found in this pastebin.

Average times:

  • Value: 0.0000885
  • Reference: 0.00009295

Final result: References are indeed slower than values, by ~5% (100 - ((0.00009295/0.0000885)*100)). Normally you would not need to worry about this performance drop though since it is so small.

File System Performance in PHP

While writing pepperminty wiki, I started seeing a rather nasty in crease in page load times. After looking into it, I drew the conclusion that it must have been the file system that caused the problem. At the time, I had multiple calls to PHP's glob function to find all the wiki pages in the current directory, and I was checking to see if the wiki page existed before reading it into memory.

The solution: A page index. To cut down on the number of reads from the file system, I created a json file that containedd inforamtion about every page on the wiki. This way, it only needs to check the existence of and read in a single file before it can start rendering any one page. If the page index doesn't exist, it is automatically rebuilt with the glob function to find all the wiki pages in the current directory.

In short: to increase the performance of your PHP application, try to reduce the number of reads (and writes!) to the file system to an absolute minimum.

I still need to update the code to allow users to delete pages via the GUI though, because at present you have to have access to the server files to delete a page and then remove it from the page index manually.

Art by Mythdael