Archive for the ‘Lua’ Category

WordPress + Lighttpd + WP-Supercache + Mobile Support

Last year I made some work on lighttpd support for wp-supercache. It instantly became very popular and basically anyone running wordpress on lighttpd uses it, even if it lacks support for wp-supercache newest features.

The amazing Jean Pierre Wenzel has recently released an updated version that adds a much needed mobile support.

You can check it out here.

Thanks Jean Pierre!

Lightning speed WordPress with Lighttpd and Supercache, part II

There was an error in the code I wrote for my previous post about lighttpd and wp-supercache. If you kept GZip disabled in you wp-supercache configuration, and your browser sent an Accepts gzip header, lightpress would serve the dynamic page (instead of the cached html page).

I did some refactoring and testing, and here’s the current version of rewrite.lua. This one will serve the correct gzipped or text content, while solving another bug with urls ending in ”/”:

function serve_html(cached_page)
  if (lighty.stat(cached_page)) then
    lighty.env["physical.path"] = cached_page
    print("Serving cached page: " .. cached_page)
    return true
  else
    return false
  end
end
 
function serve_gzip(cached_page)
  if (lighty.stat(cached_page .. ".gz")) then
    lighty.header["Content-Encoding"] = "gzip"
    lighty.header["Content-Type"] = ""
    lighty.env["physical.path"] = cached_page .. ".gz"
    print("Serving gzipped page: " .. cached_page .. ".gz")
    return true
  else
    return false
  end
end
 
attr = lighty.stat(lighty.env["physical.path"])
 
if (not attr) then
  lighty.env["uri.path"] = "/index.php"
  lighty.env["physical.rel-path"] = lighty.env["uri.path"]
  lighty.env["physical.path"] = lighty.env["physical.doc-root"] .. lighty.env["physical.rel-path"]
 
  query_condition = not (lighty.env["uri.query"] and string.find(lighty.env["uri.query"], ".*s=.*"))
  user_cookie = lighty.request["Cookie"] or "no_cookie_here"
  cookie_condition = not (string.find(user_cookie, ".*comment_author.*") or string.find(user_cookie, ".*wordpress.*") or string.find(user_cookie, ".*wp-postpass_.*"))
  if (query_condition and cookie_condition) then
    accept_encoding = lighty.request["Accept-Encoding"] or "no_acceptance"
    cached_page = lighty.env["physical.doc-root"] .. "/wp-content/cache/supercache/" .. lighty.request["Host"] .. lighty.env["request.uri"] .. "/index.html"
    cached_page = string.gsub(cached_page, "//", "/")
    if (string.find(accept_encoding, "gzip")) then
      if not serve_gzip(cached_page) then serve_html(cached_page) end
    else
      serve_html(cached_page)
    end
  end
end

Lighttpd and WP-Supercache? Now you can!

Update: there are some bugs with this code. You can find the newest (and best) version here

It’s often said that if you can’t find something in Google it doesn’t exist, and when I couldn’t find a way to serve WP-Supercached pages via Lighttpd I was pretty sure no one had ever published on the net a solution to my problem.

Nice permalinks were easy to fix, thanks to this tutorial, but cache was a no-go: the lighttpd wiki and the wordpress forums had no info, so I had to cook a solution for myself.

It was easier than I thought though:

-- rewrite.lua, in your WP_ROOT
attr = lighty.stat(lighty.env["physical.path"])
 
if (not attr) then
  lighty.env["uri.path"] = "/index.php"
  lighty.env["physical.rel-path"] = lighty.env["uri.path"]
  lighty.env["physical.path"] = lighty.env["physical.doc-root"] .. lighty.env["physical.rel-path"]
 
  query_condition = not (lighty.env["uri.query"] and string.find(lighty.env["uri.query"], ".*s=.*"))
  user_cookie = lighty.request["Cookie"] or "no_cookie_here"
  cookie_condition = not (string.find(user_cookie, ".*comment_author.*") or string.find(user_cookie, ".*wordpress.*") or string.find(user_cookie, ".*wp-postpass_.*"))
  if (query_condition and cookie_condition) then
    accept_encoding = lighty.request["Accept-Encoding"] or "no_acceptance"
    cached_page = lighty.env["physical.doc-root"] .. "/wp-content/cache/supercache/" .. lighty.request["Host"] .. lighty.env["request.uri"] .. "/index.html"
    if (string.find(accept_encoding, "gzip")) then
      if (lighty.stat(cached_page .. ".gz")) then
        lighty.header["Content-Encoding"] = "gzip"
        lighty.header["Content-Type"] = ""
        lighty.env["physical.path"] = cached_page
      end
    else
      if (lighty.stat(cached_page)) then
        lighty.env["physical.path"] = cached_page
      end
    end
  end
end

This rewrite.lua will serve compressed cached pages to those who accept gzip and plain html to those who prefer not to get gzip, while retaining the nice permalinks.

The battle of the languages part II

My previous post about a programming contest I had with my friends was wildly popular. Much much more than I even thought possible.

I started with a simple comparison of PHP, C, Ruby, Erlang and Javascript and ended up with lots of comments where people posted interesting implementations in more and more languages, even obscure ones (to me) like Haskell and Ocaml.

I owe everyone a fairer benchmark so I will do the test again, this time testing the following languages:

  • C
  • Common Lisp
  • Erlang
  • Haskell
  • Javascript
  • Java
  • Ocaml
  • Perl
  • PHP
  • Python
  • Ruby

I need submissions for most of these languages, and I actually am quite open to submissions for the languages I speak :)

The rules are simple, the program has to store the results in an array (not just count them) and has to run without any strange libraries or compilers or compiler switches. To avoid interpreter starting time problems, please submit programs that autotime themselves.

As usual we’ll find the pythagorean triplets up to 5000. The reference implementation is the following, in Ruby:

t = Time.now
result = []
2.upto(5000) do |c| 
  1.upto(c-1) do |b|
    a = Math.sqrt(c*c - b*b)
    result << [a.to_i, b, c] if a.to_i == a 
  end
end
puts Time.now - t

This code takes 15.70s to run on my macbook pro.

Now it’s your turn!

Update: Lua version by Sindisil

local tt = os.clock()
local result = {}
local c
  for c = 2, 5000 do
    local b
    for b = 1, c-1 do
      local a = math.sqrt(c*c - b*b)
      if a == math.floor(a) then
      result[#result+1] = { a, b, c }
    end
  end
end
print(os.clock() - tt)

It takes 5.48s to run on my box.

Update: new Ruby version.

include Math
 
a, b, c = 0
result = []
2.upto(5000) do |c| 
  d = c * c
  1.upto(c-1) do |b|
    a = sqrt(d - b*b)
    result << [a.floor, b, c] if a.floor == a 
  end
end
puts Process.times[0]

Following Gabriele Renzi’s suggestions we now have a faster ruby version: 12.30s

Update: faster Lua version from Chris Swetenham, it runs in 3.44s

local tt = os.clock()
local result = {}
local c
local n = 1
local math = math
local sqrt = math.sqrt
local floor = math.floor
 
for c = 2, 5000 do
  local b
  for b = 1, c-1 do
    local a = sqrt(c*c - b*b)
    if a == floor(a) then
      result[n] = { a, b, c }
      n = n + 1
    end
  end
end
 
print(os.clock() - tt)

Update: PHP version by Fullo

<?php
$start = microtime(true);
$a = $b = $c = 0;
$result = array();
 
for ($c = 2; $c <= 5000; $c++) {
  for ($b = 1; $b < $c; $b++) {
    $a = sqrt($c*$c - $b*$b);
	if (intval($a) == $a) 
       $result[] = array($a,$b,$c);              
  }
}
echo (microtime(true) - $start);
?>

It runs in 9.73s.

Update: Python version from ludo, it runs in 11.2s

from time import clock
 
start = clock()
 
from math import sqrt
 
results = []
 
for c in xrange(2, 5001):
  d = c * c
  for b in xrange(1, c):
    a = sqrt(d - b * b)
    if a % 1 == 0.0:
      results.append((a, b, c))
 
print clock() - start

The results for now:

  1. Lua 3.44
  2. PHP 9.73
  3. Python 11.20
  4. Ruby 12.30