[pypy-commit] extradoc extradoc: (Mike Pall) improve lua versions of benchmarks

cfbolz noreply at buildbot.pypy.org
Fri Aug 17 13:51:14 CEST 2012


Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: extradoc
Changeset: r4671:ba7c27ac8a13
Date: 2012-08-17 13:50 +0200
http://bitbucket.org/pypy/extradoc/changeset/ba7c27ac8a13/

Log:	(Mike Pall) improve lua versions of benchmarks

diff --git a/talk/dls2012/benchmarks/convolution/convolution.lua b/talk/dls2012/benchmarks/convolution/convolution.lua
--- a/talk/dls2012/benchmarks/convolution/convolution.lua
+++ b/talk/dls2012/benchmarks/convolution/convolution.lua
@@ -1,13 +1,13 @@
 module(..., package.seeall);
 local ffi = require("ffi")
 
-function array(length, initializer)
+local function array(length, initializer)
     return ffi.new("double[?]", length, initializer)
 end
 
 -- _______________ conv3 _______________
 
-function _conv3(a, arraylength, k, n)
+local function _conv3(a, arraylength, k, n)
     assert(#k == 3)
     local b = array(arraylength - 2, 0)
     while n > 0 do
@@ -20,7 +20,7 @@
     return b
 end
 
-function conv3(n)
+local function conv3(n)
     local arraylength = 100000000/n
     _conv3(array(arraylength, 1), arraylength,
            {-1, 0, 1}, n)
@@ -29,7 +29,7 @@
 
 -- _______________ conv5 _______________
 
-function _conv5(a, arraylength, k, n)
+local function _conv5(a, arraylength, k, n)
     assert(#k == 5)
     n = n or 1
     local b = array(arraylength - 4, 0)
@@ -43,7 +43,7 @@
     return b
 end
 
-function conv5(n)
+local function conv5(n)
     local arraylength = 100000000/n
     _conv5(array(arraylength, 1), arraylength,
            {1, 4, 6, 4, 1}, n)
@@ -54,101 +54,86 @@
 
 -- begin class Array2D
 
-Array2D = {
-
-    new = function(self, w, h, initializer)
-        initializer = initializer or 0
-        return setmetatable(
-            {width = w, height = h, data=array(w * h, initializer)}, self)
-    end,
-
-    __tostring = function(self)
-        return string.format("Array2D(%d, %d)", self.width, self.height)
-    end,
-
-    idx = function(self, x, y)
-        return y * self.width + x
-    end,
-
-    get = function(self, x, y)
-        return self.data[self:idx(x, y)]
-    end,
-
-    set = function(self, x, y, val)
-        self.data[self:idx(x, y)] = val
-    end,
-}
-
-Array2D.__index = Array2D
+local mt = { __index = function(o, x) return o.a[x] end }
+local tc = {}
+local function Array2D(w, h)
+  local t = tc[w*2^20+h]
+  if not t then
+    t = ffi.typeof("struct { int width, height; double a[$][$]; }", w, h)
+    tc[w*2^20+h] = t
+    ffi.metatype(t, mt)
+  end
+  return t(w, h)
+end
 
 -- end class Array2D
 
-function _conv3x3(a, b, k)
+local function _conv3x3(a, b, k)
     assert(k.width == 3 and k.height == 3)
     for y = 1, a.height - 2     do
         for x = 1, a.width - 2 do
-            b:set(x, y, k:get(2, 2) * a:get(x - 1, y - 1) + k:get(1, 2) * a:get(x, y - 1) + k:get(0, 2) * a:get(x + 1, y - 1) +
-                        k:get(2, 1) * a:get(x - 1, y) + k:get(1, 1) * a:get(x, y) + k:get(0, 1) * a:get(x + 1, y) +
-                        k:get(2, 0) * a:get(x - 1, y + 1) + k:get(1, 0) * a:get(x, y + 1) + k:get(0, 0) * a:get(x + 1, y + 1))
+            b[x][y] = k[2][2] * a[x-1][y-1] + k[1][2] * a[x][y-1] + k[0][2] * a[x+1][y-1] +
+                      k[2][1] * a[x-1][y]   + k[1][1] * a[x][y]   + k[0][1] * a[x+1][y]   +
+		      k[2][0] * a[x-1][y+1] + k[1][0] * a[x][y+1] + k[0][0] * a[x+1][y+1]
         end
     end
     return b
 end
 
-function conv3x3(x, y)
-    local a = Array2D:new(x, y)
-    local b = Array2D:new(x, y)
+local function conv3x3(x, y)
+    local a = Array2D(x, y)
+    local b = Array2D(x, y)
     for i = 1, 10 do
-        _conv3x3(a, b, Array2D:new(3, 3))
+        _conv3x3(a, b, Array2D(3, 3))
     end
     return string.format("conv3x3(Array2D(%dx%d))", x, y)
 end
 
 
-function morphology3x3(a, b, k, func)
+local function morphology3x3(a, b, k, func)
     assert(k.width == 3 and k.height == 3)
     for y = 1, a.height - 2 do
         for x = 1, a.width - 2 do
-            b:set(x, y, func(k:get(2, 2) * a:get(x - 1, y - 1), k:get(1, 2) * a:get(x, y - 1), k:get(0, 2) * a:get(x + 1, y - 1),
-                             k:get(2, 1) * a:get(x - 1, y), k:get(1, 1) * a:get(x, y), k:get(0, 1) * a:get(x + 1, y),
-                             k:get(2, 0) * a:get(x - 1, y + 1), k:get(1, 0) * a:get(x, y + 1), k:get(0, 0) * a:get(x + 1, y + 1)))
+            b[x][y] = func(k[2][2] * a[x-1][y-1], k[1][2] * a[x][y-1], k[0][2] * a[x+1][y-1],
+                           k[2][1] * a[x-1][y],   k[1][1] * a[x][y],   k[0][1] * a[x+1][y],
+                           k[2][0] * a[x-1][y+1], k[1][0] * a[x][y+1], k[0][0] * a[x+1][y+1])
         end
     end
     return b
 end
 
-function _dilate3x3(a, b, k)
+local function _dilate3x3(a, b, k)
     return morphology3x3(a, b, k, math.max)
 end
 
-function dilate3x3(x, y)
-    local a = Array2D:new(x, y)
-    local b = Array2D:new(x, y)
+local function dilate3x3(x, y)
+    local a = Array2D(x, y)
+    local b = Array2D(x, y)
     for i = 1, 10 do
-        _dilate3x3(a, b, Array2D:new(3, 3))
+        _dilate3x3(a, b, Array2D(3, 3))
     end
     return string.format("dilate3x3(Array2D(%dx%d))", x, y)
 end
 
-function _sobel_magnitude(a)
-    b = Array2D:new(a.width, a.height)
+local function _sobel_magnitude(a)
+    local b = Array2D(a.width, a.height)
     for y = 1, a.height - 2 do
         for x = 1, a.width - 2 do
-            local dx = -1 * a:get(x - 1, y - 1) + 1 * a:get(x + 1, y - 1) +
-                       -2 * a:get(x - 1, y) + 2 * a:get(x + 1, y) +
-                       -1 * a:get(x - 1, y + 1) + 1 * a:get(x + 1, y + 1)
-            local dy = -1 * a:get(x - 1, y - 1) - 2 * a:get(x, y - 1) - 1 * a:get(x + 1, y - 1) +
-                        1 * a:get(x - 1, y + 1) + 2 * a:get(x, y + 1) + 1 * a:get(x + 1, y + 1)
-            b:set(x, y, math.sqrt(dx * dx + dy * dy) / 4)
+            local dx = -1 * a[x-1][y-1] + 1 * a[x+1][y-1] +
+                       -2 * a[x-1][y]   + 2 * a[x+1][y] +
+                       -1 * a[x-1][y+1] + 1 * a[x+1][y+1]
+            local dy = -1 * a[x-1][y-1] - 2 * a[x][y-1]-1 * a[x+1][y-1] +
+                        1 * a[x-1][y+1] + 2 * a[x][y+1]+1 * a[x+1][y+1]
+            b[x][y] = math.sqrt(dx * dx + dy * dy) / 4
         end
     end
     return b
 end
 
 
-function sobel_magnitude(x, y)
+local function sobel_magnitude(x, y)
     for i = 1, 10 do
-        _sobel_magnitude(Array2D:new(x, y))
+        _sobel_magnitude(Array2D(x, y))
     end
     return string.format('sobel(Array2D(%sx%s))', x, y)
 end
@@ -156,20 +141,18 @@
 
 -- entry point
 function main(args)
-    arg = args[1]
-    num = tonumber(args[2])
+    local arg = args[1]
+    local num = tonumber(args[2]) or 1000
+    local num2 = tonumber(args[3]) or num
     if arg == "conv3" then
         return conv3(num)
     elseif arg == "conv5" then
         return conv5(num)
     elseif arg == "conv3x3" then
-        num2 = tonumber(args[3])
         return conv3x3(num, num2)
     elseif arg == "dilate3x3" then
-        num2 = tonumber(args[3])
         return dilate3x3(num, num2)
     elseif arg == "sobel_magnitude" then
-        num2 = tonumber(args[3])
         return sobel_magnitude(num, num2)
     end
 end
diff --git a/talk/dls2012/benchmarks/sqrt/sqrt.lua b/talk/dls2012/benchmarks/sqrt/sqrt.lua
--- a/talk/dls2012/benchmarks/sqrt/sqrt.lua
+++ b/talk/dls2012/benchmarks/sqrt/sqrt.lua
@@ -1,102 +1,62 @@
 module(..., package.seeall);
 
+local ffi = require("ffi")
 local bit = require("bit")
-local lshift, rshift, tobit = bit.lshift, bit.rshift, bit.tobit
-
-if true then
-    function rshift(a, b)
-        return a / (2 ^ b)
-    end
-
-    function lshift(a, b)
-        return a * (2 ^ b)
-    end
-
-    function tobit(a)
-        return a
-    end
-end
+local lshift, rshift = bit.lshift, bit.rshift
 
 ---------------------------
 
-function sqrt(y, n)
-    n = n or 10000
-    local x = y / 2
-    while n > 0 do
-        n = n - 1
-        x = (x + y/x) / 2
-    end
-    return x
+local function sqrt(y, n)
+  local x = y / 2
+  for n=n or 10000,0,-1 do x = (x + y/x) / 2 end
+  return x
 end
 
 -----------------------
 -- begin class Fix16 --
 -----------------------
 
-Fix16 = {
-    new = function(self, val, scale)
-        if scale == nil then
-            scale = true
-        end
+local Fix16 = ffi.typeof("struct { int val; }")
+local new, istype = ffi.new, ffi.istype
 
-        if type(val) == "table" then
-            val = val.val
-        else
-            if scale == true then
-                val = lshift(val, 16)
-            else
-                val = tobit(val)
-            end
-        end
-        return setmetatable({val=val}, self)
-    end,
-
-    __add = function(self, other)
-        return Fix16:new(self.val + Fix16:new(other).val, false)
-    end,
-
-    __mul = function(self, other)
-        local value = rshift(self.val, 8) * (rshift(Fix16:new(other).val, 8))
-        return Fix16:new(value, false)
-    end,
-
-    __div = function(self, other)
-        local value = lshift(self.val, 8) / (rshift(Fix16:new(other).val, 8))
-        return Fix16:new(value, false)
-    end,
-
-    to_float = function(self)
-        return self.val / (2 ^ 16)
-    end,
-
-    __tostring = function(self)
-        return tostring(self:to_float())
-    end,
-}
-Fix16.__index = Fix16
+ffi.metatype(Fix16, {
+  __new = function(t, a)
+    if istype(Fix16, a) then return a end
+    return new(Fix16, lshift(a, 16))
+  end,
+  __add = function(a, b)
+    return new(Fix16, Fix16(a).val + Fix16(b).val)
+  end,
+  __div = function(a, b)
+    return new(Fix16, lshift(Fix16(a).val, 8) / rshift(Fix16(b).val, 8))
+  end,
+  __index = {
+    to_float = function(a) return a.val / 2^16 end,
+  },
+})
 
 ---------------------
 -- end class Fix16 --
 ---------------------
 
-function test_sqrt()
-    t = {2, 3, 4, 5, 6, 7, 8, 9, 123}
+local function test_sqrt()
+    local t = {2, 3, 4, 5, 6, 7, 8, 9, 123}
     for j = 1, #t do
-        i = t[j]
-        s = string.format("%d %f %f %f %f", i, sqrt(i), sqrt(tobit(i)), sqrt(Fix16:new(i)):to_float(), math.sqrt(i))
+        local i = t[j]
+        local s = string.format("%d %f %f %f %f", i, sqrt(i), sqrt(i), sqrt(Fix16(i)):to_float(), math.sqrt(i))
         print(s)
     end
 end
 
 -- entry point
 function main(args)
-    arg = args[1]
+    local arg = args[1]
     if arg == "int" then
         sqrt(123, 100000000)
     elseif arg == "float" then
         sqrt(123, 100000000)
     elseif arg == "Fix16" then
-        sqrt(Fix16:new(123), 100000000)
+        sqrt(Fix16(123), 100000000)
     elseif arg == "test_sqrt" then
         test_sqrt()
     else


More information about the pypy-commit mailing list