From 0ff65845af8f2b3c9cb2d8b2d97640bfa4c79556 Mon Sep 17 00:00:00 2001 From: Leonid Meleshin Date: Mon, 1 Jul 2024 00:22:58 +0400 Subject: [PATCH] feat(Lua): add some benchmarks --- Dockerfile | 13 ++++ lua/benchmark.yml | 17 ++++++ lua/mandelbrot/Simple.lua | 63 +++++++++++++++++++ lua/primes/Simple.lua | 40 ++++++++++++ lua/recursion/Tak.lua | 20 ++++++ lua/treap/Naive.lua | 125 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 278 insertions(+) create mode 100644 lua/benchmark.yml create mode 100644 lua/mandelbrot/Simple.lua create mode 100644 lua/primes/Simple.lua create mode 100644 lua/recursion/Tak.lua create mode 100644 lua/treap/Naive.lua diff --git a/Dockerfile b/Dockerfile index 58cd1c7..1f1a142 100644 --- a/Dockerfile +++ b/Dockerfile @@ -174,4 +174,17 @@ RUN wget --progress=dot:giga -O - \ https://download.swift.org/swift-${SWIFT}-release/debian12/swift-${SWIFT}-RELEASE/swift-${SWIFT}-RELEASE-debian12.tar.gz | tar -xz ENV PATH="/opt/swift-${SWIFT}-RELEASE-debian12/usr/bin:${PATH}" +# Lua +RUN apt install -y \ + lua5.4 \ + luajit + +# C# +RUN wget https://packages.microsoft.com/config/debian/12/packages-microsoft-prod.deb -O packages-microsoft-prod.deb \ + && dpkg -i packages-microsoft-prod.deb \ + && rm packages-microsoft-prod.deb \ + && apt update \ + && apt install -y \ + dotnet-sdk-8.0 aspnetcore-runtime-8.0 dotnet-runtime-8.0 mono-complete + WORKDIR /app diff --git a/lua/benchmark.yml b/lua/benchmark.yml new file mode 100644 index 0000000..2d8e0d5 --- /dev/null +++ b/lua/benchmark.yml @@ -0,0 +1,17 @@ +title: 'Lua' + +strategy: + matrix: + command: + - title: 'Lua' + command: 'lua %s' + - title: 'LuaJIT' + command: 'luajit %s' + tags: + - JIT + + files: + - primes/Simple.lua + - treap/Naive.lua + - recursion/Tak.lua + - mandelbrot/Simple.lua diff --git a/lua/mandelbrot/Simple.lua b/lua/mandelbrot/Simple.lua new file mode 100644 index 0000000..33f3ccf --- /dev/null +++ b/lua/mandelbrot/Simple.lua @@ -0,0 +1,63 @@ +#!/usr/bin/env lua + +function index() + for y = -39, 38 do + io.write("\n") + + for x = -39, 38 do + local i = mandelbrot( + x / 40.0, + y / 40.0 + ) + + if i == 0 then + io.write("*") + else + io.write(" ") + end + end + end + + io.write("\n") +end + +function mandelbrot(x, y) + local cr = y - 0.5 + local ci = x + local zi = 0.0 + local zr = 0.0 + local i = 0 + + while true do + i = i + 1 + + local temp = zr * zi + + local zr2 = zr * zr + local zi2 = zi * zi + + zr = zr2 - zi2 + cr + zi = temp + temp + ci + + if zi2 + zr2 > 16 then + return i + end + + if i > 5000 then + return 0 + end + end +end + +local function main() + local startTime = os.clock() + + index() + + local endTime = os.clock() + local duration = (endTime - startTime) * 1000 + + print(string.format("Execution time: %.0fms", duration)) +end + +main() diff --git a/lua/primes/Simple.lua b/lua/primes/Simple.lua new file mode 100644 index 0000000..16437c9 --- /dev/null +++ b/lua/primes/Simple.lua @@ -0,0 +1,40 @@ +#!/usr/bin/env lua + +local NUMBER = 1000000 + +local function getLastPrime(count) + local lastPrime = 2 + + -- Traverse each number from 3 to N, skipping even numbers + for i = 3, count, 2 do + local isPrime = true + local limit = math.floor(math.sqrt(i)) + + for j = 3, limit, 2 do + if i % j == 0 then + isPrime = false + break + end + end + + if isPrime then + lastPrime = i + end + end + + return lastPrime +end + +local function main() + local startTime = os.clock() + + local lastPrime = getLastPrime(NUMBER) + print("Last prime: " .. lastPrime) + + local endTime = os.clock() + local durationMs = (endTime - startTime) * 1000 + + print("Execution time: " .. durationMs .. "ms") +end + +main() diff --git a/lua/recursion/Tak.lua b/lua/recursion/Tak.lua new file mode 100644 index 0000000..3860bdd --- /dev/null +++ b/lua/recursion/Tak.lua @@ -0,0 +1,20 @@ +local function tak(x, y, z) + if y < x then + return tak(tak(x - 1, y, z), tak(y - 1, z, x), tak(z - 1, x, y)) + else + return z + end +end + +local function benchmark() + local startTime = os.clock() * 1000 + + print(tak(30, 22, 12)) + + local endTime = os.clock() * 1000 + local duration = endTime - startTime + + print("Execution time: " .. duration .. "ms") +end + +benchmark() diff --git a/lua/treap/Naive.lua b/lua/treap/Naive.lua new file mode 100644 index 0000000..814949d --- /dev/null +++ b/lua/treap/Naive.lua @@ -0,0 +1,125 @@ +math.randomseed(os.time()) + +Node = {} +Node.__index = Node + +function Node:new(x) + local instance = setmetatable({}, self) + instance.x = x + instance.y = math.random() + instance.left = nil + instance.right = nil + return instance +end + +function merge(lower, greater) + if lower == nil then + return greater + end + + if greater == nil then + return lower + end + + if lower.y < greater.y then + lower.right = merge(lower.right, greater) + return lower + else + greater.left = merge(lower, greater.left) + return greater + end +end + +function splitBinary(orig, value) + if orig == nil then + return nil, nil + end + + if orig.x < value then + local rightLower, rightGreater = splitBinary(orig.right, value) + orig.right = rightLower + return orig, rightGreater + else + local leftLower, leftGreater = splitBinary(orig.left, value) + orig.left = leftGreater + return leftLower, orig + end +end + +function merge3(lower, equal, greater) + return merge(merge(lower, equal), greater) +end + +SplitResult = {} +SplitResult.__index = SplitResult + +function SplitResult:new(lower, equal, greater) + local instance = setmetatable({}, self) + instance.lower = lower + instance.equal = equal + instance.greater = greater + return instance +end + +function split(orig, value) + local lower, equalGreater = splitBinary(orig, value) + local equal, greater = splitBinary(equalGreater, value + 1) + return SplitResult:new(lower, equal, greater) +end + +Tree = {} +Tree.__index = Tree + +function Tree:new() + local instance = setmetatable({}, self) + instance.root = nil + return instance +end + +function Tree:hasValue(x) + local splited = split(self.root, x) + local res = splited.equal ~= nil + self.root = merge3(splited.lower, splited.equal, splited.greater) + return res +end + +function Tree:insert(x) + local splited = split(self.root, x) + if splited.equal == nil then + splited.equal = Node:new(x) + end + self.root = merge3(splited.lower, splited.equal, splited.greater) +end + +function Tree:erase(x) + local splited = split(self.root, x) + self.root = merge(splited.lower, splited.greater) +end + +function main() + local tree = Tree:new() + local cur = 5 + local res = 0 + + for i = 1, 999999 do + local a = i % 3 + cur = (cur * 57 + 43) % 10007 + + if a == 0 then + tree:insert(cur) + elseif a == 1 then + tree:erase(cur) + elseif a == 2 then + res = res + (tree:hasValue(cur) and 1 or 0) + end + end + + print(res) +end + +local startTimeMs = math.floor(os.clock() * 1000) +main() +local endTimeMs = math.floor(os.clock() * 1000) +local durationMs = endTimeMs - startTimeMs + +print("Execution time: " .. durationMs .. "ms")