SlideShare a Scribd company logo
1 of 125
Download to read offline
Что такое Rspamd
• Система фильтрации спама с ориентацией на производительность
• OpenSource проект
• Плагины и правила написаны на языке Lua
• Ядро написано на plain (old) C
Lua и C
В Rspamd
Lua
C
Соотношение Lua и C
По строкам кода
0
35000
70000
105000
140000
Plain C
Lua
Assembly Other
Perl
Соотношение Lua и C
По количеству плагинов
0
8
15
23
30
6
26
Lua C
Что написано на Lua
• Правила, а также комбинации регулярных выражений
• Большая часть плагинов:
• Проверка DNS списков
• Взаимодействие с Redis (репутация, “серые” списки, динамические настройки, список ответов,
динамические лимиты)
• Работа с внешними сервисами (антивирусы, запись в ClickHouse итд)
• Контент-фильтрация
• Работа с нейросетями и классификацией текстов
• Работа с SpamAssassin правилами
Почему Lua?
Экскурс в историю
K&R определение функции
Странный синтаксис переменных
Что это?
Надо больше макросов!
Похоже, это обычный C
Правило на Lua
Встраиваемый язык
Каким он должен быть
Встраиваемый язык
Каким он должен быть
• Минимум внешних зависимостей (JavaScript)
Встраиваемый язык
Каким он должен быть
• Минимум внешних зависимостей (JavaScript)
• Простота синтаксиса (Perl)
Встраиваемый язык
Каким он должен быть
• Минимум внешних зависимостей (JavaScript)
• Простота синтаксиса (Perl)
• Скорость работы (Python, Guile, TCL)
Встраиваемый язык
Каким он должен быть
• Минимум внешних зависимостей (JavaScript)
• Простота синтаксиса (Perl)
• Скорость работы (Python, Guile, TCL)
• Скорость переключения между C и встраиваемым языком
Что дал переход на Lua
Что дал переход на Lua
• Появилось несколько активных авторов плагинов и правил на Lua
Что дал переход на Lua
• Появилось несколько активных авторов плагинов и правил на Lua
• Появились юнит-тесты на Lua
Что дал переход на Lua
• Появилось несколько активных авторов плагинов и правил на Lua
• Появились юнит-тесты на Lua
• Текущий подход к разработке: писать Lua биндинги на Си, а основную
логику на Lua
Что дал переход на Lua
• Появилось несколько активных авторов плагинов и правил на Lua
• Появились юнит-тесты на Lua
• Текущий подход к разработке: писать Lua биндинги на Си, а основную
логику на Lua
• Упростилось написание утилит командной строки
Особенности Lua
Кривая обучения Lua
Начал писать на Lua
Обучение Lua
That was my first ever attempt at Lua, I asked you to add halfOpen
support to your lua_tcp module, which you did within about 30 mins
and I had the plugin written an working within an hour or so.
Обучение Lua
• Плагин опроса внешнего сервиса DCC:
That was my first ever attempt at Lua, I asked you to add halfOpen
support to your lua_tcp module, which you did within about 30 mins
and I had the plugin written an working within an hour or so.
Обучение Lua
• Плагин опроса внешнего сервиса DCC:
• написан за час времени
That was my first ever attempt at Lua, I asked you to add halfOpen
support to your lua_tcp module, which you did within about 30 mins
and I had the plugin written an working within an hour or so.
Обучение Lua
• Плагин опроса внешнего сервиса DCC:
• написан за час времени
• человеком, без знаний Lua
That was my first ever attempt at Lua, I asked you to add halfOpen
support to your lua_tcp module, which you did within about 30 mins
and I had the plugin written an working within an hour or so.
Обучение Lua
• Плагин опроса внешнего сервиса DCC:
• написан за час времени
• человеком, без знаний Lua
• еще 30 минут заняла адаптация биндингов на C
That was my first ever attempt at Lua, I asked you to add halfOpen
support to your lua_tcp module, which you did within about 30 mins
and I had the plugin written an working within an hour or so.
Обучение Lua
• Плагин опроса внешнего сервиса DCC:
• написан за час времени
• человеком, без знаний Lua
• еще 30 минут заняла адаптация биндингов на C
• аналог на перле - больше 1k строк кода
That was my first ever attempt at Lua, I asked you to add halfOpen
support to your lua_tcp module, which you did within about 30 mins
and I had the plugin written an working within an hour or so.
Некоторые особенности Lua
Общие характеристики языка
Некоторые особенности Lua
Общие характеристики языка
• Крайне простой синтаксис (20 правил в BNF грамматике)
Некоторые особенности Lua
Общие характеристики языка
• Крайне простой синтаксис (20 правил в BNF грамматике)
• Таблицы - универсальный инструмент работы с данными
Некоторые особенности Lua
Общие характеристики языка
• Крайне простой синтаксис (20 правил в BNF грамматике)
• Таблицы - универсальный инструмент работы с данными
• Функции - объекты первого рода (возможны функциональные
конструкции и замыкания)
Некоторые особенности Lua
Общие характеристики языка
• Крайне простой синтаксис (20 правил в BNF грамматике)
• Таблицы - универсальный инструмент работы с данными
• Функции - объекты первого рода (возможны функциональные
конструкции и замыкания)
• Стандартная библиотека содержит только необходимый минимум
функций
Некоторые особенности Lua
Общие характеристики языка
• Крайне простой синтаксис (20 правил в BNF грамматике)
• Таблицы - универсальный инструмент работы с данными
• Функции - объекты первого рода (возможны функциональные
конструкции и замыкания)
• Стандартная библиотека содержит только необходимый минимум
функций
• Динамическая строгая типизация
Синтаксис Lua
Основные элементы
Синтаксис Lua
Основные элементы
• Переменные:
Синтаксис Lua
Основные элементы
• Переменные: local ret = false -- Generic variable
local rules = {} -- Empty table
local rspamd_logger = require “rspamd_logger" -- Load rspamd module
Синтаксис Lua
Основные элементы
• Переменные:
• Условия:
local ret = false -- Generic variable
local rules = {} -- Empty table
local rspamd_logger = require “rspamd_logger" -- Load rspamd module
Синтаксис Lua
Основные элементы
• Переменные:
• Условия:
local ret = false -- Generic variable
local rules = {} -- Empty table
local rspamd_logger = require “rspamd_logger" -- Load rspamd module
if not ret then -- can use ‘not’, ‘and’, ‘or’ here
…
elseif ret ~= 10 then -- note ~= for ‘not equal’ operator
end
Синтаксис Lua
Основные элементы
• Переменные:
• Условия:
• Циклы:
local ret = false -- Generic variable
local rules = {} -- Empty table
local rspamd_logger = require “rspamd_logger" -- Load rspamd module
if not ret then -- can use ‘not’, ‘and’, ‘or’ here
…
elseif ret ~= 10 then -- note ~= for ‘not equal’ operator
end
Синтаксис Lua
Основные элементы
• Переменные:
• Условия:
• Циклы:
local ret = false -- Generic variable
local rules = {} -- Empty table
local rspamd_logger = require “rspamd_logger" -- Load rspamd module
if not ret then -- can use ‘not’, ‘and’, ‘or’ here
…
elseif ret ~= 10 then -- note ~= for ‘not equal’ operator
end
for k,m in pairs(opts) do … end -- Iterate over keyed table a[‘key’] =
value
for _,i in ipairs(images) do … end -- Iterate over array table a[1] =
value
for i=1,10 do … end -- Count from 1 to 10
Синтаксис Lua
Основные элементы
• Переменные:
• Условия:
• Циклы:
• Таблицы:
local ret = false -- Generic variable
local rules = {} -- Empty table
local rspamd_logger = require “rspamd_logger" -- Load rspamd module
if not ret then -- can use ‘not’, ‘and’, ‘or’ here
…
elseif ret ~= 10 then -- note ~= for ‘not equal’ operator
end
for k,m in pairs(opts) do … end -- Iterate over keyed table a[‘key’] =
value
for _,i in ipairs(images) do … end -- Iterate over array table a[1] =
value
for i=1,10 do … end -- Count from 1 to 10
Синтаксис Lua
Основные элементы
• Переменные:
• Условия:
• Циклы:
• Таблицы:
local ret = false -- Generic variable
local rules = {} -- Empty table
local rspamd_logger = require “rspamd_logger" -- Load rspamd module
if not ret then -- can use ‘not’, ‘and’, ‘or’ here
…
elseif ret ~= 10 then -- note ~= for ‘not equal’ operator
end
for k,m in pairs(opts) do … end -- Iterate over keyed table a[‘key’] =
value
for _,i in ipairs(images) do … end -- Iterate over array table a[1] =
value
for i=1,10 do … end -- Count from 1 to 10
local options = { [1] = ‘value’, [‘key’] = 1, -- Numbers starts from 1
another_key = function(task) … end, -- Functions can be values
[2] = {} -- Other tables can be values
} -- Can have both numbers and strings as key and anything as values
Синтаксис Lua
Основные элементы
• Переменные:
• Условия:
• Циклы:
• Таблицы:
• Функции:
local ret = false -- Generic variable
local rules = {} -- Empty table
local rspamd_logger = require “rspamd_logger" -- Load rspamd module
if not ret then -- can use ‘not’, ‘and’, ‘or’ here
…
elseif ret ~= 10 then -- note ~= for ‘not equal’ operator
end
for k,m in pairs(opts) do … end -- Iterate over keyed table a[‘key’] =
value
for _,i in ipairs(images) do … end -- Iterate over array table a[1] =
value
for i=1,10 do … end -- Count from 1 to 10
local options = { [1] = ‘value’, [‘key’] = 1, -- Numbers starts from 1
another_key = function(task) … end, -- Functions can be values
[2] = {} -- Other tables can be values
} -- Can have both numbers and strings as key and anything as values
Синтаксис Lua
Основные элементы
• Переменные:
• Условия:
• Циклы:
• Таблицы:
• Функции:
local ret = false -- Generic variable
local rules = {} -- Empty table
local rspamd_logger = require “rspamd_logger" -- Load rspamd module
if not ret then -- can use ‘not’, ‘and’, ‘or’ here
…
elseif ret ~= 10 then -- note ~= for ‘not equal’ operator
end
for k,m in pairs(opts) do … end -- Iterate over keyed table a[‘key’] =
value
for _,i in ipairs(images) do … end -- Iterate over array table a[1] =
value
for i=1,10 do … end -- Count from 1 to 10
local options = { [1] = ‘value’, [‘key’] = 1, -- Numbers starts from 1
another_key = function(task) … end, -- Functions can be values
[2] = {} -- Other tables can be values
} -- Can have both numbers and strings as key and anything as values
local function something(task) -- Normal definition
local cb = function(data) -- Functions can be nested
…
end
end
Таблицы в Lua
Таблицы в Lua
Основные определения
Таблицы в Lua
Основные определения
• Значения - все, кроме nil:
Таблицы в Lua
Основные определения
• Значения - все, кроме nil: local t = {
1, -- number
'test', -- string
function() end, -- function
{1, 2, 3} -- another table
task:get_mempool(), -- userdata
}
Таблицы в Lua
Основные определения
• Значения - все, кроме nil: local t = {
1, -- number
'test', -- string
function() end, -- function
{1, 2, 3} -- another table
task:get_mempool(), -- userdata
}
• Ключи - строки и числа:
Таблицы в Lua
Основные определения
• Значения - все, кроме nil: local t = {
1, -- number
'test', -- string
function() end, -- function
{1, 2, 3} -- another table
task:get_mempool(), -- userdata
}
local t = {
1, -- 1
[3] = {1,2},
test = function() end,
['spaces in key'] = 'abc',
[1.2] = 3,
[-1] = 4,
}
• Ключи - строки и числа:
Таблицы в Lua
table
local table = {
a = 1,
b = 2,
[1] = 3,
[2] = function() end,
[0] = true
}
3
function() end
true
1
2
1
2
0
‘a’
‘b’
Массив Хеш таблица
!
Таблицы в Lua
Итерация
local t = {
a = 1,
b = 2,
[1] = 3,
[2] = function() end,
[0] = true
}
Массив
Таблица
целиком
1..2
Метатаблицы
Когда просто таблиц недостаточно
• Задают общие свойства для других таблиц
• Примерно соответствуют Prototype в JavaScript
• Позволяют задавать функции-методы для таблиц (через __newindex или __index)
• Могут также задавать операторы над таблицами (например, через __eq или
__sum)
• Можно задавать метатаблицы для стандартных Lua типов (например, строк)
• Используются в C API для определения методов для типа userdata
Функции в Lua
Функции в Lua
Основные элементы
Функции в Lua
Основные элементы
• Могут быть вложенными:
Функции в Lua
Основные элементы
• Могут быть вложенными:
function foo(n) -- global function
local var = function(m) -- function in var
return m + n -- n is from `foo`
end
local function bar() -- another form of var
return var(2)
end
return bar()
end
Функции в Lua
Основные элементы
• Могут быть вложенными:
function foo(n) -- global function
local var = function(m) -- function in var
return m + n -- n is from `foo`
end
local function bar() -- another form of var
return var(2)
end
return bar()
end
• Могут быть аргументами и
возвращаться из функций:
Функции в Lua
Основные элементы
• Могут быть вложенными:
function foo(n) -- global function
local var = function(m) -- function in var
return m + n -- n is from `foo`
end
local function bar() -- another form of var
return var(2)
end
return bar()
end
local function f(cb) -- accepts callback function
return function(args) -- accepts some args
return cb(args) -- return callback function from args (decorator like)
end
end
• Могут быть аргументами и
возвращаться из функций:
Функции в Lua
Замыкания
function test(n)
local f = function()
return n + 1 -- n is captured
end
n = n + 1 -- n in f is also modified
return а
end
test(1) -- Returns function closure
test(1)() -- Returns 3
Функции в Lua
Замыкания
function test(n)
local f = function()
return n + 1 -- n is captured
end
n = n + 1 -- n in f is also modified
return а
end
test(1) -- Returns function closure
test(1)() -- Returns 3
Замыкание
Функции в Lua
Замыкания
function test(n)
local f = function()
return n + 1 -- n is captured
end
n = n + 1 -- n in f is also modified
return а
end
test(1) -- Returns function closure
test(1)() -- Returns 3
Замыкание
Функции в Lua
Замыкания
function test(n)
local f = function()
return n + 1 -- n is captured
end
n = n + 1 -- n in f is also modified
return а
end
test(1) -- Returns function closure
test(1)() -- Returns 3
Замыкание
Переменные входят по ссылке
Функции в Lua
Замыкания
function test(n)
local f = function()
return n + 1 -- n is captured
end
n = n + 1 -- n in f is also modified
return а
end
test(1) -- Returns function closure
test(1)() -- Returns 3
Замыкание
Переменные входят по ссылке
Можно возвращать функцию
Функции в Lua
Замыкания
function test(n)
local f = function()
return n + 1 -- n is captured
end
n = n + 1 -- n in f is also modified
return а
end
test(1) -- Returns function closure
test(1)() -- Returns 3
Замыкание
Переменные входят по ссылке
Функция-замыкание
Можно возвращать функцию
Функции в Lua
Замыкания
function test(n)
local f = function()
return n + 1 -- n is captured
end
n = n + 1 -- n in f is also modified
return а
end
test(1) -- Returns function closure
test(1)() -- Returns 3
Замыкание
Переменные входят по ссылке
Функция-замыкание
Непосредственно вызов
Можно возвращать функцию
Функции в Lua
• Позволяют писать в функциональном стиле (библиотека lua-fun)
• Замыкания работают также для C функций
• Передача по ссылке несколько необычна, но эффективна
• Время жизни замыкания ассоциируется с переменной, в которой оно
хранится
Строки в Lua
Строки в Lua
Передача строки из C
Глобальный хеш
строк
s1
s2
s3
lua_pushstring (L, "hello");
hello
Копия
Хеш
hash(hello)
Поиск
Строки в Lua
Передача строки из C
Глобальный хеш
строк
s1
s2
s3
lua_pushstring (L, "hello");
hello
Вставка
hello
Строки в Lua
• Строки в Lua неизменяемы
• Сравнение строк - просто сравнение указателей: O(1)
• Создание и передача строк - дорогая операция
• Если нужно делать строку из кусков, то нужно использовать таблицу
и table.concat
Строки в Lua
Секунды(меньше-лучше)
0
75
150
225
300
Naive concat Table.concat
6.7c
274c
40x
Строки в Lua
Передача текста
C C
Userdata
const char *s
size_t len
refcounter
Взаимодействие Lua и C
Виртуальный стек
Общий вид
1
2
3
4
-4
-3
-2
-1 lua_gettop() ⟹4
PushPop
Виртуальный стек
Добавление значений
1
2
3
4
-6
-5
-4
-3
lua_pushnumbernumber
string
5
6
-2
-1 lua_pushstring
Push
Виртуальный стек
Извлечение значений
1
2
3
4
-3
-2
-1
lua_pop(L, 3);number
string
5
6
Pop
Виртуальный стек
Вызов функции
1
2
3
4
-3
-2
-1
5
6
Внутренние переменые
number
string
4
5
-2
-1
Аргументы
Возвращаемые значения
Проблемы работы со стеком
Проблемы работы со стеком
• Скорость: переключение занимает около сотни CPU cycles
Проблемы работы со стеком
• Скорость: переключение занимает около сотни CPU cycles
• Проблемы контроля: без специальных ключей компиляции легко
получить низкоуровневые ошибки (вплоть до полного падения)
Проблемы работы со стеком
• Скорость: переключение занимает около сотни CPU cycles
• Проблемы контроля: без специальных ключей компиляции легко
получить низкоуровневые ошибки (вплоть до полного падения)
Проблемы работы со стеком
• Скорость: переключение занимает около сотни CPU cycles
• Проблемы контроля: без специальных ключей компиляции легко
получить низкоуровневые ошибки (вплоть до полного падения)
• Крайне неочевидный код
Проблемы работы со стеком
• Скорость: переключение занимает около сотни CPU cycles
• Проблемы контроля: без специальных ключей компиляции легко
получить низкоуровневые ошибки (вплоть до полного падения)
• Крайне неочевидный код
• Есть ряд сложных моментов (итерация по таблице)
Пример из практики
Итерация по таблице
lua_pushvalue (L, i); /* Push table on top */
lua_pushnil (L); /* Push nil to start iterate */
while (lua_next (L, -2)) {
lua_pushvalue (L, -2); /* Copy key as it is special */
key = luaL_checkstring (L, -1);
value = luaL_checkstring (L, -2);
lua_pop (L, 2); /* Remove key and value leaving original key */
}
lua_pop (L, 1); /* Remove table */
Пример из практики
Итерация по таблице
lua_pushvalue (L, i); tabletop -1
Пример из практики
Итерация по таблице
lua_pushvalue (L, i);
lua_pushnil (L);
tabletop -2
nil -1
Пример из практики
Итерация по таблице
table -2
nil -1
while (lua_next (L, -2))
table -3
key -2
value -1
Предыдущий ключ
Новый ключ
Пример из практики
Итерация по таблице
lua_pushvalue (L, -2);
key = luaL_checkstring (L, -1);
value = luaL_checkstring (L, -2);
table
-2
key
-1
value
key copy
-3
-4
Пример из практики
Итерация по таблице
lua_pop (L, 2);
table
-2
key
-1
value
key copy
-3
-4
table
key -1
-2
while (lua_next (L, -2))
Используется для следующей итерации
FFI вызовы кода на C
Плюсы FFI
• Очень быстро работают для простых типов (десяток циклов)
• Поддерживают все конструкции C99
• Поддерживают типы-обертки (boxed types), например 64-х битные
целые
• Проще поддерживать
FFI вызовы
Синтетические тесты
Секунды(меньше-лучше)
0
10
20
30
40
tanh(x) strcmp(s1, s2)
Plain call FFI Plain call FFI
5.97c
3.13c
4.38c
30.07c
10x
Пример из практики
Оптимизация узких мест
local ffi
if type(jit) == 'table' then
ffi = require("ffi")
ffi.cdef[[
int rspamd_re_cache_type_from_string (const char *str);
int rspamd_re_cache_process_ffi (void *ptask,
void *pre,
int type,
const char *type_data,
int is_strong);
]]
end
local function process_regexp_opt(re, task, re_type, header, strong)
if type(jit) == 'table' then
-- Use ffi call
local itype = ffi.C.rspamd_re_cache_type_from_string(re_type)
if not strong then
strong = 0
else
string = 1
end
local iret = ffi.C.rspamd_re_cache_process_ffi (task, re, itype, header, strong)
return tonumber(iret)
else
return task:process_regexp(re, re_type, header, strong)
end
end
Проверка
LuaJIT
local ffi
if type(jit) == 'table' then
ffi = require("ffi")
ffi.cdef[[
int rspamd_re_cache_type_from_string (const char *str);
int rspamd_re_cache_process_ffi (void *ptask,
void *pre,
int type,
const char *type_data,
int is_strong);
]]
end
local function process_regexp_opt(re, task, re_type, header, strong)
if type(jit) == 'table' then
-- Use ffi call
local itype = ffi.C.rspamd_re_cache_type_from_string(re_type)
if not strong then
strong = 0
else
string = 1
end
local iret = ffi.C.rspamd_re_cache_process_ffi (task, re, itype, header, strong)
return tonumber(iret)
else
return task:process_regexp(re, re_type, header, strong)
end
end
Определение С функций
Пример из практики
Оптимизация узких мест
local ffi
if type(jit) == 'table' then
ffi = require("ffi")
ffi.cdef[[
int rspamd_re_cache_type_from_string (const char *str);
int rspamd_re_cache_process_ffi (void *ptask,
void *pre,
int type,
const char *type_data,
int is_strong);
]]
end
local function process_regexp_opt(re, task, re_type, header, strong)
if type(jit) == 'table' then
-- Use ffi call
local itype = ffi.C.rspamd_re_cache_type_from_string(re_type)
if not strong then
strong = 0
else
string = 1
end
local iret = ffi.C.rspamd_re_cache_process_ffi (task, re, itype, header, strong)
return tonumber(iret)
else
return task:process_regexp(re, re_type, header, strong)
end
end
FFI call
Userdata to C pointer
bool -> int
Пример из практики
Оптимизация узких мест
local ffi
if type(jit) == 'table' then
ffi = require("ffi")
ffi.cdef[[
int rspamd_re_cache_type_from_string (const char *str);
int rspamd_re_cache_process_ffi (void *ptask,
void *pre,
int type,
const char *type_data,
int is_strong);
]]
end
local function process_regexp_opt(re, task, re_type, header, strong)
if type(jit) == 'table' then
-- Use ffi call
local itype = ffi.C.rspamd_re_cache_type_from_string(re_type)
if not strong then
strong = 0
else
string = 1
end
local iret = ffi.C.rspamd_re_cache_process_ffi (task, re, itype, header, strong)
return tonumber(iret)
else
return task:process_regexp(re, re_type, header, strong)
end
end
Plain call
Пример из практики
Оптимизация узких мест
Оптимизация FFI вызовов
Lua вызов
FFI вызов
Проблемы FFI
Проблемы FFI
• Поддерживаются на ограниченном количестве архитектур (Sparc64)
Проблемы FFI
• Поддерживаются на ограниченном количестве архитектур (Sparc64)
• В plain Lua требуют отдельного модуля FFI, LuaJIT поддерживает “из
коробки”
Проблемы FFI
• Поддерживаются на ограниченном количестве архитектур (Sparc64)
• В plain Lua требуют отдельного модуля FFI, LuaJIT поддерживает “из
коробки”
• Нет проверки типов, нет контроля целостности памяти
Проблемы FFI
• Поддерживаются на ограниченном количестве архитектур (Sparc64)
• В plain Lua требуют отдельного модуля FFI, LuaJIT поддерживает “из
коробки”
• Нет проверки типов, нет контроля целостности памяти
Проблемы FFI
• Поддерживаются на ограниченном количестве архитектур (Sparc64)
• В plain Lua требуют отдельного модуля FFI, LuaJIT поддерживает “из
коробки”
• Нет проверки типов, нет контроля целостности памяти
Проблемы FFI
• Поддерживаются на ограниченном количестве архитектур (Sparc64)
• В plain Lua требуют отдельного модуля FFI, LuaJIT поддерживает “из
коробки”
• Нет проверки типов, нет контроля целостности памяти
• Не всегда быстрее
Проблемы FFI
• Поддерживаются на ограниченном количестве архитектур (Sparc64)
• В plain Lua требуют отдельного модуля FFI, LuaJIT поддерживает “из
коробки”
• Нет проверки типов, нет контроля целостности памяти
• Не всегда быстрее
• Очень сложно сделать sandbox
Выводы
Выводы
Выводы
• Lua простой для изучения
Выводы
• Lua простой для изучения
Выводы
• Lua простой для изучения
• Lua удобен для встраивания
Выводы
• Lua простой для изучения
• Lua удобен для встраивания
Выводы
Выводы
• Основной инструмент - таблицы
Выводы
• Основной инструмент - таблицы
Выводы
• Основной инструмент - таблицы
• Основной инструмент - функции
Выводы
• Основной инструмент - таблицы
• Основной инструмент - функции
Выводы
Выводы
• Lua - быстрый язык (особенно LuaJIT)
Выводы
• Lua - быстрый язык (особенно LuaJIT)
Выводы
• Lua - быстрый язык (особенно LuaJIT)
• Некоторые оптимизации бывают опасны
Выводы
• Lua - быстрый язык (особенно LuaJIT)
• Некоторые оптимизации бывают опасны
Всеволод Стахов
vstakhov@rspamd.com
Вопросы

More Related Content

What's hot

"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)
"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)
"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)
Badoo Development
 
Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)
Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)
Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)
Ontico
 
Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...
Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...
Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...
Ontico
 
Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...
Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...
Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...
Ontico
 
Сага о кластере. Все что вы хотели знать про горизонтальное масштабирование в...
Сага о кластере. Все что вы хотели знать про горизонтальное масштабирование в...Сага о кластере. Все что вы хотели знать про горизонтальное масштабирование в...
Сага о кластере. Все что вы хотели знать про горизонтальное масштабирование в...
Ontico
 

What's hot (20)

Современная операционная система: что надо знать разработчику / Александр Кри...
Современная операционная система: что надо знать разработчику / Александр Кри...Современная операционная система: что надо знать разработчику / Александр Кри...
Современная операционная система: что надо знать разработчику / Александр Кри...
 
pgconf.ru 2015 avito postgresql
pgconf.ru 2015 avito postgresqlpgconf.ru 2015 avito postgresql
pgconf.ru 2015 avito postgresql
 
Консольные приложения на Go
Консольные приложения на GoКонсольные приложения на Go
Консольные приложения на Go
 
"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)
"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)
"Почему язык Lua — это интересно?", Ник Заварицкий, (Mail.ru Group)
 
Оптимизация работы с данными в мобильных приложениях / Святослав Иванов, Артё...
Оптимизация работы с данными в мобильных приложениях / Святослав Иванов, Артё...Оптимизация работы с данными в мобильных приложениях / Святослав Иванов, Артё...
Оптимизация работы с данными в мобильных приложениях / Святослав Иванов, Артё...
 
Как устроена MySQL-репликация / Андрей Аксенов (Sphinx)
Как устроена MySQL-репликация / Андрей Аксенов (Sphinx)Как устроена MySQL-репликация / Андрей Аксенов (Sphinx)
Как устроена MySQL-репликация / Андрей Аксенов (Sphinx)
 
My talk at Highload++ 2015
My talk at Highload++ 2015My talk at Highload++ 2015
My talk at Highload++ 2015
 
nginx.CHANGES.2015 / Игорь Сысоев, Валентин Бартенев (Nginx)
nginx.CHANGES.2015 / Игорь Сысоев, Валентин Бартенев (Nginx)nginx.CHANGES.2015 / Игорь Сысоев, Валентин Бартенев (Nginx)
nginx.CHANGES.2015 / Игорь Сысоев, Валентин Бартенев (Nginx)
 
Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)
Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)
Сравнение форматов и библиотек сериализации / Антон Рыжов (Qrator Labs)
 
Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...
Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...
Производительность запросов в PostgreSQL - шаг за шагом / Илья Космодемьянски...
 
Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...
Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...
Open Source SQL-базы данных вступили в эру миллионов запросов в секунду / Фед...
 
Денис Иванов
Денис ИвановДенис Иванов
Денис Иванов
 
Дмитрий Новиков - Tarantool в Badoo
Дмитрий Новиков - Tarantool в BadooДмитрий Новиков - Tarantool в Badoo
Дмитрий Новиков - Tarantool в Badoo
 
Поиск наизнанку
Поиск наизнанкуПоиск наизнанку
Поиск наизнанку
 
Что нового и полезного в PostgreSQL 9.5 / Илья Космодемьянский (PostgreSQL-Co...
Что нового и полезного в PostgreSQL 9.5 / Илья Космодемьянский (PostgreSQL-Co...Что нового и полезного в PostgreSQL 9.5 / Илья Космодемьянский (PostgreSQL-Co...
Что нового и полезного в PostgreSQL 9.5 / Илья Космодемьянский (PostgreSQL-Co...
 
MySQL 5.7 - NoSQL - JSON, Protocol X, Document Store / Петр Зайцев (Percona)
MySQL 5.7 - NoSQL - JSON, Protocol X, Document Store / Петр Зайцев (Percona)MySQL 5.7 - NoSQL - JSON, Protocol X, Document Store / Петр Зайцев (Percona)
MySQL 5.7 - NoSQL - JSON, Protocol X, Document Store / Петр Зайцев (Percona)
 
Avito Stachka 2012
Avito Stachka 2012Avito Stachka 2012
Avito Stachka 2012
 
Сага о кластере. Все что вы хотели знать про горизонтальное масштабирование в...
Сага о кластере. Все что вы хотели знать про горизонтальное масштабирование в...Сага о кластере. Все что вы хотели знать про горизонтальное масштабирование в...
Сага о кластере. Все что вы хотели знать про горизонтальное масштабирование в...
 
Linux API с точки зрения разработчика веб-сервера / Валентин Бартенев (NGINX,...
Linux API с точки зрения разработчика веб-сервера / Валентин Бартенев (NGINX,...Linux API с точки зрения разработчика веб-сервера / Валентин Бартенев (NGINX,...
Linux API с точки зрения разработчика веб-сервера / Валентин Бартенев (NGINX,...
 
Внутреннее устройство PostgreSQL: временные таблицы и фрагментация памяти / Г...
Внутреннее устройство PostgreSQL: временные таблицы и фрагментация памяти / Г...Внутреннее устройство PostgreSQL: временные таблицы и фрагментация памяти / Г...
Внутреннее устройство PostgreSQL: временные таблицы и фрагментация памяти / Г...
 

Viewers also liked

Применяем стандарты кодирования NASA к JavaScript / Денис Радин (Liberty Global)
Применяем стандарты кодирования NASA к JavaScript / Денис Радин (Liberty Global)Применяем стандарты кодирования NASA к JavaScript / Денис Радин (Liberty Global)
Применяем стандарты кодирования NASA к JavaScript / Денис Радин (Liberty Global)
Ontico
 
Промышленное ускорение сайтов / Николай Мациевский (Айри.рф)
Промышленное ускорение сайтов / Николай Мациевский (Айри.рф)Промышленное ускорение сайтов / Николай Мациевский (Айри.рф)
Промышленное ускорение сайтов / Николай Мациевский (Айри.рф)
Ontico
 
RTB в телевизоре и на улицах / Михаил Мельников (IPONWEB)
RTB в телевизоре и на улицах / Михаил Мельников (IPONWEB)RTB в телевизоре и на улицах / Михаил Мельников (IPONWEB)
RTB в телевизоре и на улицах / Михаил Мельников (IPONWEB)
Ontico
 
Автоматизация тестирования клиентской производительности / Николай Лавлинский...
Автоматизация тестирования клиентской производительности / Николай Лавлинский...Автоматизация тестирования клиентской производительности / Николай Лавлинский...
Автоматизация тестирования клиентской производительности / Николай Лавлинский...
Ontico
 
Anti-fraud solutions in RTB / Вадим Антонюк (IPONWEB)
Anti-fraud solutions in RTB / Вадим Антонюк (IPONWEB)Anti-fraud solutions in RTB / Вадим Антонюк (IPONWEB)
Anti-fraud solutions in RTB / Вадим Антонюк (IPONWEB)
Ontico
 
Отрисовать за 16 мс / Глеб Михеев (Beta Digital Production)
Отрисовать за 16 мс / Глеб Михеев (Beta Digital Production)Отрисовать за 16 мс / Глеб Михеев (Beta Digital Production)
Отрисовать за 16 мс / Глеб Михеев (Beta Digital Production)
Ontico
 
Семантическое ядро рунета - высоконагруженная сontent-based рекомендательная ...
Семантическое ядро рунета - высоконагруженная сontent-based рекомендательная ...Семантическое ядро рунета - высоконагруженная сontent-based рекомендательная ...
Семантическое ядро рунета - высоконагруженная сontent-based рекомендательная ...
Ontico
 
Хочу знать, сколько уникальных посетителей было на моём сайте за произвольный...
Хочу знать, сколько уникальных посетителей было на моём сайте за произвольный...Хочу знать, сколько уникальных посетителей было на моём сайте за произвольный...
Хочу знать, сколько уникальных посетителей было на моём сайте за произвольный...
Ontico
 
Побеждаем мейнфрейм / Андрей Николаенко (IBS)
Побеждаем мейнфрейм / Андрей Николаенко (IBS)Побеждаем мейнфрейм / Андрей Николаенко (IBS)
Побеждаем мейнфрейм / Андрей Николаенко (IBS)
Ontico
 
AWS и GCP: трудная жизнь в облаках / Максим Пугачев (IPONWEB)
AWS и GCP: трудная жизнь в облаках / Максим Пугачев (IPONWEB)AWS и GCP: трудная жизнь в облаках / Максим Пугачев (IPONWEB)
AWS и GCP: трудная жизнь в облаках / Максим Пугачев (IPONWEB)
Ontico
 
Сайт под управлением ERP или ERP под управлением сайта / Станислав Гоц (Lamod...
Сайт под управлением ERP или ERP под управлением сайта / Станислав Гоц (Lamod...Сайт под управлением ERP или ERP под управлением сайта / Станислав Гоц (Lamod...
Сайт под управлением ERP или ERP под управлением сайта / Станислав Гоц (Lamod...
Ontico
 
Особенности архитектуры распределённого хранилища в Dropbox / Слава Бахмутов ...
Особенности архитектуры распределённого хранилища в Dropbox / Слава Бахмутов ...Особенности архитектуры распределённого хранилища в Dropbox / Слава Бахмутов ...
Особенности архитектуры распределённого хранилища в Dropbox / Слава Бахмутов ...
Ontico
 
5 способов деплоя PHP-кода в условиях хайлоада / Юрий Насретдинов (Badoo)
5 способов деплоя PHP-кода в условиях хайлоада / Юрий Насретдинов (Badoo)5 способов деплоя PHP-кода в условиях хайлоада / Юрий Насретдинов (Badoo)
5 способов деплоя PHP-кода в условиях хайлоада / Юрий Насретдинов (Badoo)
Ontico
 

Viewers also liked (20)

Применяем стандарты кодирования NASA к JavaScript / Денис Радин (Liberty Global)
Применяем стандарты кодирования NASA к JavaScript / Денис Радин (Liberty Global)Применяем стандарты кодирования NASA к JavaScript / Денис Радин (Liberty Global)
Применяем стандарты кодирования NASA к JavaScript / Денис Радин (Liberty Global)
 
Промышленное ускорение сайтов / Николай Мациевский (Айри.рф)
Промышленное ускорение сайтов / Николай Мациевский (Айри.рф)Промышленное ускорение сайтов / Николай Мациевский (Айри.рф)
Промышленное ускорение сайтов / Николай Мациевский (Айри.рф)
 
A/Б-тестирование: от сегментирования до профита / Кирилл Котов (Superjob)
A/Б-тестирование: от сегментирования до профита / Кирилл Котов (Superjob)A/Б-тестирование: от сегментирования до профита / Кирилл Котов (Superjob)
A/Б-тестирование: от сегментирования до профита / Кирилл Котов (Superjob)
 
RTB в телевизоре и на улицах / Михаил Мельников (IPONWEB)
RTB в телевизоре и на улицах / Михаил Мельников (IPONWEB)RTB в телевизоре и на улицах / Михаил Мельников (IPONWEB)
RTB в телевизоре и на улицах / Михаил Мельников (IPONWEB)
 
Your hero images need you: Save the day with HTTP2 image loading / Tobias Bal...
Your hero images need you: Save the day with HTTP2 image loading / Tobias Bal...Your hero images need you: Save the day with HTTP2 image loading / Tobias Bal...
Your hero images need you: Save the day with HTTP2 image loading / Tobias Bal...
 
Continuous Integration на стероидах / Александр Акбашев (HERE)
Continuous Integration на стероидах / Александр Акбашев (HERE)Continuous Integration на стероидах / Александр Акбашев (HERE)
Continuous Integration на стероидах / Александр Акбашев (HERE)
 
Измеряем энергопотребление с помощью Arduino / Алексей Лавренюк (Яндекс)
Измеряем энергопотребление с помощью Arduino / Алексей Лавренюк (Яндекс)Измеряем энергопотребление с помощью Arduino / Алексей Лавренюк (Яндекс)
Измеряем энергопотребление с помощью Arduino / Алексей Лавренюк (Яндекс)
 
Автоматизация тестирования клиентской производительности / Николай Лавлинский...
Автоматизация тестирования клиентской производительности / Николай Лавлинский...Автоматизация тестирования клиентской производительности / Николай Лавлинский...
Автоматизация тестирования клиентской производительности / Николай Лавлинский...
 
Anti-fraud solutions in RTB / Вадим Антонюк (IPONWEB)
Anti-fraud solutions in RTB / Вадим Антонюк (IPONWEB)Anti-fraud solutions in RTB / Вадим Антонюк (IPONWEB)
Anti-fraud solutions in RTB / Вадим Антонюк (IPONWEB)
 
Отрисовать за 16 мс / Глеб Михеев (Beta Digital Production)
Отрисовать за 16 мс / Глеб Михеев (Beta Digital Production)Отрисовать за 16 мс / Глеб Михеев (Beta Digital Production)
Отрисовать за 16 мс / Глеб Михеев (Beta Digital Production)
 
Порядок для скорости. Система структурирования фронтендовой части веб-приложе...
Порядок для скорости. Система структурирования фронтендовой части веб-приложе...Порядок для скорости. Система структурирования фронтендовой части веб-приложе...
Порядок для скорости. Система структурирования фронтендовой части веб-приложе...
 
Семантическое ядро рунета - высоконагруженная сontent-based рекомендательная ...
Семантическое ядро рунета - высоконагруженная сontent-based рекомендательная ...Семантическое ядро рунета - высоконагруженная сontent-based рекомендательная ...
Семантическое ядро рунета - высоконагруженная сontent-based рекомендательная ...
 
Хочу знать, сколько уникальных посетителей было на моём сайте за произвольный...
Хочу знать, сколько уникальных посетителей было на моём сайте за произвольный...Хочу знать, сколько уникальных посетителей было на моём сайте за произвольный...
Хочу знать, сколько уникальных посетителей было на моём сайте за произвольный...
 
Побеждаем мейнфрейм / Андрей Николаенко (IBS)
Побеждаем мейнфрейм / Андрей Николаенко (IBS)Побеждаем мейнфрейм / Андрей Николаенко (IBS)
Побеждаем мейнфрейм / Андрей Николаенко (IBS)
 
Опыт построения СХД на базе Windows Server для использования в публичном обла...
Опыт построения СХД на базе Windows Server для использования в публичном обла...Опыт построения СХД на базе Windows Server для использования в публичном обла...
Опыт построения СХД на базе Windows Server для использования в публичном обла...
 
AWS и GCP: трудная жизнь в облаках / Максим Пугачев (IPONWEB)
AWS и GCP: трудная жизнь в облаках / Максим Пугачев (IPONWEB)AWS и GCP: трудная жизнь в облаках / Максим Пугачев (IPONWEB)
AWS и GCP: трудная жизнь в облаках / Максим Пугачев (IPONWEB)
 
Сайт под управлением ERP или ERP под управлением сайта / Станислав Гоц (Lamod...
Сайт под управлением ERP или ERP под управлением сайта / Станислав Гоц (Lamod...Сайт под управлением ERP или ERP под управлением сайта / Станислав Гоц (Lamod...
Сайт под управлением ERP или ERP под управлением сайта / Станислав Гоц (Lamod...
 
Особенности архитектуры распределённого хранилища в Dropbox / Слава Бахмутов ...
Особенности архитектуры распределённого хранилища в Dropbox / Слава Бахмутов ...Особенности архитектуры распределённого хранилища в Dropbox / Слава Бахмутов ...
Особенности архитектуры распределённого хранилища в Dropbox / Слава Бахмутов ...
 
Как HeadHunter удалось безопасно нарушить RFC 793 (TCP) и обойти сетевые лову...
Как HeadHunter удалось безопасно нарушить RFC 793 (TCP) и обойти сетевые лову...Как HeadHunter удалось безопасно нарушить RFC 793 (TCP) и обойти сетевые лову...
Как HeadHunter удалось безопасно нарушить RFC 793 (TCP) и обойти сетевые лову...
 
5 способов деплоя PHP-кода в условиях хайлоада / Юрий Насретдинов (Badoo)
5 способов деплоя PHP-кода в условиях хайлоада / Юрий Насретдинов (Badoo)5 способов деплоя PHP-кода в условиях хайлоада / Юрий Насретдинов (Badoo)
5 способов деплоя PHP-кода в условиях хайлоада / Юрий Насретдинов (Badoo)
 

Similar to Практика совместного использования Lua и C в opensource спам-фильтре Rspamd / Всеволод Стахов (University of Cambridge, Mimecast)

Как устроена MySQL-репликация, Андрей Аксенов (Sphinx)
Как устроена MySQL-репликация, Андрей Аксенов (Sphinx)Как устроена MySQL-репликация, Андрей Аксенов (Sphinx)
Как устроена MySQL-репликация, Андрей Аксенов (Sphinx)
Ontico
 
Romanova techforum bash
Romanova techforum bashRomanova techforum bash
Romanova techforum bash
kuchinskaya
 
Alexander Dymo - IT-клуб Николаева - April 2011 - Ruby: Beaty and the Beast
Alexander Dymo - IT-клуб Николаева - April 2011 - Ruby: Beaty and the BeastAlexander Dymo - IT-клуб Николаева - April 2011 - Ruby: Beaty and the Beast
Alexander Dymo - IT-клуб Николаева - April 2011 - Ruby: Beaty and the Beast
Alexander Dymo
 
Alexander Dymo - IT Jam 2009 - Ruby: Beaty Or The Beast
Alexander Dymo - IT Jam 2009 - Ruby: Beaty Or The BeastAlexander Dymo - IT Jam 2009 - Ruby: Beaty Or The Beast
Alexander Dymo - IT Jam 2009 - Ruby: Beaty Or The Beast
Alexander Dymo
 
Сергей Еланцев - Troubleshooting
Сергей Еланцев - Troubleshooting   Сергей Еланцев - Troubleshooting
Сергей Еланцев - Troubleshooting
Yandex
 
Введение в Akka
Введение в AkkaВведение в Akka
Введение в Akka
Zheka Kozlov
 
Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013
ScalaNsk
 
Константин Осипов (Mail.Ru)
Константин Осипов (Mail.Ru)Константин Осипов (Mail.Ru)
Константин Осипов (Mail.Ru)
Ontico
 

Similar to Практика совместного использования Lua и C в opensource спам-фильтре Rspamd / Всеволод Стахов (University of Cambridge, Mimecast) (20)

Александр Гладыш — Lua
Александр Гладыш — LuaАлександр Гладыш — Lua
Александр Гладыш — Lua
 
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶  отладки в TarantoolИнструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶  отладки в Tarantool
Инструменты для з̶а̶х̶в̶а̶т̶а̶ ̶м̶и̶р̶а̶ отладки в Tarantool
 
Как устроена MySQL-репликация, Андрей Аксенов (Sphinx)
Как устроена MySQL-репликация, Андрей Аксенов (Sphinx)Как устроена MySQL-репликация, Андрей Аксенов (Sphinx)
Как устроена MySQL-репликация, Андрей Аксенов (Sphinx)
 
Romanova techforum bash
Romanova techforum bashRomanova techforum bash
Romanova techforum bash
 
Alexander Dymo - IT-клуб Николаева - April 2011 - Ruby: Beaty and the Beast
Alexander Dymo - IT-клуб Николаева - April 2011 - Ruby: Beaty and the BeastAlexander Dymo - IT-клуб Николаева - April 2011 - Ruby: Beaty and the Beast
Alexander Dymo - IT-клуб Николаева - April 2011 - Ruby: Beaty and the Beast
 
Зачем нужна Scala?
Зачем нужна Scala?Зачем нужна Scala?
Зачем нужна Scala?
 
PowerShell
PowerShellPowerShell
PowerShell
 
Alexander Dymo - IT Jam 2009 - Ruby: Beaty Or The Beast
Alexander Dymo - IT Jam 2009 - Ruby: Beaty Or The BeastAlexander Dymo - IT Jam 2009 - Ruby: Beaty Or The Beast
Alexander Dymo - IT Jam 2009 - Ruby: Beaty Or The Beast
 
Сергей Еланцев - Troubleshooting
Сергей Еланцев - Troubleshooting   Сергей Еланцев - Troubleshooting
Сергей Еланцев - Troubleshooting
 
Tarantool, .net, newsql
Tarantool, .net, newsqlTarantool, .net, newsql
Tarantool, .net, newsql
 
About Python
About PythonAbout Python
About Python
 
Введение в Akka
Введение в AkkaВведение в Akka
Введение в Akka
 
Rom - Ruby Object Mapper
Rom - Ruby Object MapperRom - Ruby Object Mapper
Rom - Ruby Object Mapper
 
Back to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодняBack to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодня
 
Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013
 
CI/CD-приложений на Tarantool: от пустого репозитория — до продакшна
CI/CD-приложений на Tarantool: от пустого репозитория — до продакшнаCI/CD-приложений на Tarantool: от пустого репозитория — до продакшна
CI/CD-приложений на Tarantool: от пустого репозитория — до продакшна
 
Константин Осипов (Mail.Ru)
Константин Осипов (Mail.Ru)Константин Осипов (Mail.Ru)
Константин Осипов (Mail.Ru)
 
Making of external DSL for Django ORM - Павел Петлинский, Rambler&Co
Making of external DSL for Django ORM - Павел Петлинский, Rambler&CoMaking of external DSL for Django ORM - Павел Петлинский, Rambler&Co
Making of external DSL for Django ORM - Павел Петлинский, Rambler&Co
 
TT
TTTT
TT
 
Template Toolkit – зло!?
Template Toolkit – зло!?Template Toolkit – зло!?
Template Toolkit – зло!?
 

More from Ontico

Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Ontico
 

More from Ontico (20)

One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
One-cloud — система управления дата-центром в Одноклассниках / Олег Анастасье...
 
Масштабируя DNS / Артем Гавриченков (Qrator Labs)
Масштабируя DNS / Артем Гавриченков (Qrator Labs)Масштабируя DNS / Артем Гавриченков (Qrator Labs)
Масштабируя DNS / Артем Гавриченков (Qrator Labs)
 
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
Создание BigData-платформы для ФГУП Почта России / Андрей Бащенко (Luxoft)
 
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
Готовим тестовое окружение, или сколько тестовых инстансов вам нужно / Алекса...
 
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
Новые технологии репликации данных в PostgreSQL / Александр Алексеев (Postgre...
 
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)
 
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
Inexpensive Datamasking for MySQL with ProxySQL — Data Anonymization for Deve...
 
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
Опыт разработки модуля межсетевого экранирования для MySQL / Олег Брославский...
 
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
ProxySQL Use Case Scenarios / Alkin Tezuysal (Percona)
 
MySQL Replication — Advanced Features / Петр Зайцев (Percona)
MySQL Replication — Advanced Features / Петр Зайцев (Percona)MySQL Replication — Advanced Features / Петр Зайцев (Percona)
MySQL Replication — Advanced Features / Петр Зайцев (Percona)
 
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
Внутренний open-source. Как разрабатывать мобильное приложение большим количе...
 
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
Подробно о том, как Causal Consistency реализовано в MongoDB / Михаил Тюленев...
 
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
Балансировка на скорости проводов. Без ASIC, без ограничений. Решения NFWare ...
 
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
Перехват трафика — мифы и реальность / Евгений Усков (Qrator Labs)
 
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
И тогда наверняка вдруг запляшут облака! / Алексей Сушков (ПЕТЕР-СЕРВИС)
 
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
Как мы заставили Druid работать в Одноклассниках / Юрий Невиницин (OK.RU)
 
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
Разгоняем ASP.NET Core / Илья Вербицкий (WebStoating s.r.o.)
 
100500 способов кэширования в Oracle Database или как достичь максимальной ск...
100500 способов кэширования в Oracle Database или как достичь максимальной ск...100500 способов кэширования в Oracle Database или как достичь максимальной ск...
100500 способов кэширования в Oracle Database или как достичь максимальной ск...
 
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
Apache Ignite Persistence: зачем Persistence для In-Memory, и как он работает...
 
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
Механизмы мониторинга баз данных: взгляд изнутри / Дмитрий Еманов (Firebird P...
 

Практика совместного использования Lua и C в opensource спам-фильтре Rspamd / Всеволод Стахов (University of Cambridge, Mimecast)

  • 1.
  • 2. Что такое Rspamd • Система фильтрации спама с ориентацией на производительность • OpenSource проект • Плагины и правила написаны на языке Lua • Ядро написано на plain (old) C
  • 3. Lua и C В Rspamd Lua C
  • 4. Соотношение Lua и C По строкам кода 0 35000 70000 105000 140000 Plain C Lua Assembly Other Perl
  • 5. Соотношение Lua и C По количеству плагинов 0 8 15 23 30 6 26 Lua C
  • 6. Что написано на Lua • Правила, а также комбинации регулярных выражений • Большая часть плагинов: • Проверка DNS списков • Взаимодействие с Redis (репутация, “серые” списки, динамические настройки, список ответов, динамические лимиты) • Работа с внешними сервисами (антивирусы, запись в ClickHouse итд) • Контент-фильтрация • Работа с нейросетями и классификацией текстов • Работа с SpamAssassin правилами
  • 9. K&R определение функции Странный синтаксис переменных Что это? Надо больше макросов!
  • 13. Встраиваемый язык Каким он должен быть • Минимум внешних зависимостей (JavaScript)
  • 14. Встраиваемый язык Каким он должен быть • Минимум внешних зависимостей (JavaScript) • Простота синтаксиса (Perl)
  • 15. Встраиваемый язык Каким он должен быть • Минимум внешних зависимостей (JavaScript) • Простота синтаксиса (Perl) • Скорость работы (Python, Guile, TCL)
  • 16. Встраиваемый язык Каким он должен быть • Минимум внешних зависимостей (JavaScript) • Простота синтаксиса (Perl) • Скорость работы (Python, Guile, TCL) • Скорость переключения между C и встраиваемым языком
  • 18. Что дал переход на Lua • Появилось несколько активных авторов плагинов и правил на Lua
  • 19. Что дал переход на Lua • Появилось несколько активных авторов плагинов и правил на Lua • Появились юнит-тесты на Lua
  • 20. Что дал переход на Lua • Появилось несколько активных авторов плагинов и правил на Lua • Появились юнит-тесты на Lua • Текущий подход к разработке: писать Lua биндинги на Си, а основную логику на Lua
  • 21. Что дал переход на Lua • Появилось несколько активных авторов плагинов и правил на Lua • Появились юнит-тесты на Lua • Текущий подход к разработке: писать Lua биндинги на Си, а основную логику на Lua • Упростилось написание утилит командной строки
  • 24. Обучение Lua That was my first ever attempt at Lua, I asked you to add halfOpen support to your lua_tcp module, which you did within about 30 mins and I had the plugin written an working within an hour or so.
  • 25. Обучение Lua • Плагин опроса внешнего сервиса DCC: That was my first ever attempt at Lua, I asked you to add halfOpen support to your lua_tcp module, which you did within about 30 mins and I had the plugin written an working within an hour or so.
  • 26. Обучение Lua • Плагин опроса внешнего сервиса DCC: • написан за час времени That was my first ever attempt at Lua, I asked you to add halfOpen support to your lua_tcp module, which you did within about 30 mins and I had the plugin written an working within an hour or so.
  • 27. Обучение Lua • Плагин опроса внешнего сервиса DCC: • написан за час времени • человеком, без знаний Lua That was my first ever attempt at Lua, I asked you to add halfOpen support to your lua_tcp module, which you did within about 30 mins and I had the plugin written an working within an hour or so.
  • 28. Обучение Lua • Плагин опроса внешнего сервиса DCC: • написан за час времени • человеком, без знаний Lua • еще 30 минут заняла адаптация биндингов на C That was my first ever attempt at Lua, I asked you to add halfOpen support to your lua_tcp module, which you did within about 30 mins and I had the plugin written an working within an hour or so.
  • 29. Обучение Lua • Плагин опроса внешнего сервиса DCC: • написан за час времени • человеком, без знаний Lua • еще 30 минут заняла адаптация биндингов на C • аналог на перле - больше 1k строк кода That was my first ever attempt at Lua, I asked you to add halfOpen support to your lua_tcp module, which you did within about 30 mins and I had the plugin written an working within an hour or so.
  • 30. Некоторые особенности Lua Общие характеристики языка
  • 31. Некоторые особенности Lua Общие характеристики языка • Крайне простой синтаксис (20 правил в BNF грамматике)
  • 32. Некоторые особенности Lua Общие характеристики языка • Крайне простой синтаксис (20 правил в BNF грамматике) • Таблицы - универсальный инструмент работы с данными
  • 33. Некоторые особенности Lua Общие характеристики языка • Крайне простой синтаксис (20 правил в BNF грамматике) • Таблицы - универсальный инструмент работы с данными • Функции - объекты первого рода (возможны функциональные конструкции и замыкания)
  • 34. Некоторые особенности Lua Общие характеристики языка • Крайне простой синтаксис (20 правил в BNF грамматике) • Таблицы - универсальный инструмент работы с данными • Функции - объекты первого рода (возможны функциональные конструкции и замыкания) • Стандартная библиотека содержит только необходимый минимум функций
  • 35. Некоторые особенности Lua Общие характеристики языка • Крайне простой синтаксис (20 правил в BNF грамматике) • Таблицы - универсальный инструмент работы с данными • Функции - объекты первого рода (возможны функциональные конструкции и замыкания) • Стандартная библиотека содержит только необходимый минимум функций • Динамическая строгая типизация
  • 38. Синтаксис Lua Основные элементы • Переменные: local ret = false -- Generic variable local rules = {} -- Empty table local rspamd_logger = require “rspamd_logger" -- Load rspamd module
  • 39. Синтаксис Lua Основные элементы • Переменные: • Условия: local ret = false -- Generic variable local rules = {} -- Empty table local rspamd_logger = require “rspamd_logger" -- Load rspamd module
  • 40. Синтаксис Lua Основные элементы • Переменные: • Условия: local ret = false -- Generic variable local rules = {} -- Empty table local rspamd_logger = require “rspamd_logger" -- Load rspamd module if not ret then -- can use ‘not’, ‘and’, ‘or’ here … elseif ret ~= 10 then -- note ~= for ‘not equal’ operator end
  • 41. Синтаксис Lua Основные элементы • Переменные: • Условия: • Циклы: local ret = false -- Generic variable local rules = {} -- Empty table local rspamd_logger = require “rspamd_logger" -- Load rspamd module if not ret then -- can use ‘not’, ‘and’, ‘or’ here … elseif ret ~= 10 then -- note ~= for ‘not equal’ operator end
  • 42. Синтаксис Lua Основные элементы • Переменные: • Условия: • Циклы: local ret = false -- Generic variable local rules = {} -- Empty table local rspamd_logger = require “rspamd_logger" -- Load rspamd module if not ret then -- can use ‘not’, ‘and’, ‘or’ here … elseif ret ~= 10 then -- note ~= for ‘not equal’ operator end for k,m in pairs(opts) do … end -- Iterate over keyed table a[‘key’] = value for _,i in ipairs(images) do … end -- Iterate over array table a[1] = value for i=1,10 do … end -- Count from 1 to 10
  • 43. Синтаксис Lua Основные элементы • Переменные: • Условия: • Циклы: • Таблицы: local ret = false -- Generic variable local rules = {} -- Empty table local rspamd_logger = require “rspamd_logger" -- Load rspamd module if not ret then -- can use ‘not’, ‘and’, ‘or’ here … elseif ret ~= 10 then -- note ~= for ‘not equal’ operator end for k,m in pairs(opts) do … end -- Iterate over keyed table a[‘key’] = value for _,i in ipairs(images) do … end -- Iterate over array table a[1] = value for i=1,10 do … end -- Count from 1 to 10
  • 44. Синтаксис Lua Основные элементы • Переменные: • Условия: • Циклы: • Таблицы: local ret = false -- Generic variable local rules = {} -- Empty table local rspamd_logger = require “rspamd_logger" -- Load rspamd module if not ret then -- can use ‘not’, ‘and’, ‘or’ here … elseif ret ~= 10 then -- note ~= for ‘not equal’ operator end for k,m in pairs(opts) do … end -- Iterate over keyed table a[‘key’] = value for _,i in ipairs(images) do … end -- Iterate over array table a[1] = value for i=1,10 do … end -- Count from 1 to 10 local options = { [1] = ‘value’, [‘key’] = 1, -- Numbers starts from 1 another_key = function(task) … end, -- Functions can be values [2] = {} -- Other tables can be values } -- Can have both numbers and strings as key and anything as values
  • 45. Синтаксис Lua Основные элементы • Переменные: • Условия: • Циклы: • Таблицы: • Функции: local ret = false -- Generic variable local rules = {} -- Empty table local rspamd_logger = require “rspamd_logger" -- Load rspamd module if not ret then -- can use ‘not’, ‘and’, ‘or’ here … elseif ret ~= 10 then -- note ~= for ‘not equal’ operator end for k,m in pairs(opts) do … end -- Iterate over keyed table a[‘key’] = value for _,i in ipairs(images) do … end -- Iterate over array table a[1] = value for i=1,10 do … end -- Count from 1 to 10 local options = { [1] = ‘value’, [‘key’] = 1, -- Numbers starts from 1 another_key = function(task) … end, -- Functions can be values [2] = {} -- Other tables can be values } -- Can have both numbers and strings as key and anything as values
  • 46. Синтаксис Lua Основные элементы • Переменные: • Условия: • Циклы: • Таблицы: • Функции: local ret = false -- Generic variable local rules = {} -- Empty table local rspamd_logger = require “rspamd_logger" -- Load rspamd module if not ret then -- can use ‘not’, ‘and’, ‘or’ here … elseif ret ~= 10 then -- note ~= for ‘not equal’ operator end for k,m in pairs(opts) do … end -- Iterate over keyed table a[‘key’] = value for _,i in ipairs(images) do … end -- Iterate over array table a[1] = value for i=1,10 do … end -- Count from 1 to 10 local options = { [1] = ‘value’, [‘key’] = 1, -- Numbers starts from 1 another_key = function(task) … end, -- Functions can be values [2] = {} -- Other tables can be values } -- Can have both numbers and strings as key and anything as values local function something(task) -- Normal definition local cb = function(data) -- Functions can be nested … end end
  • 48. Таблицы в Lua Основные определения
  • 49. Таблицы в Lua Основные определения • Значения - все, кроме nil:
  • 50. Таблицы в Lua Основные определения • Значения - все, кроме nil: local t = { 1, -- number 'test', -- string function() end, -- function {1, 2, 3} -- another table task:get_mempool(), -- userdata }
  • 51. Таблицы в Lua Основные определения • Значения - все, кроме nil: local t = { 1, -- number 'test', -- string function() end, -- function {1, 2, 3} -- another table task:get_mempool(), -- userdata } • Ключи - строки и числа:
  • 52. Таблицы в Lua Основные определения • Значения - все, кроме nil: local t = { 1, -- number 'test', -- string function() end, -- function {1, 2, 3} -- another table task:get_mempool(), -- userdata } local t = { 1, -- 1 [3] = {1,2}, test = function() end, ['spaces in key'] = 'abc', [1.2] = 3, [-1] = 4, } • Ключи - строки и числа:
  • 53. Таблицы в Lua table local table = { a = 1, b = 2, [1] = 3, [2] = function() end, [0] = true } 3 function() end true 1 2 1 2 0 ‘a’ ‘b’ Массив Хеш таблица !
  • 54. Таблицы в Lua Итерация local t = { a = 1, b = 2, [1] = 3, [2] = function() end, [0] = true } Массив Таблица целиком 1..2
  • 55. Метатаблицы Когда просто таблиц недостаточно • Задают общие свойства для других таблиц • Примерно соответствуют Prototype в JavaScript • Позволяют задавать функции-методы для таблиц (через __newindex или __index) • Могут также задавать операторы над таблицами (например, через __eq или __sum) • Можно задавать метатаблицы для стандартных Lua типов (например, строк) • Используются в C API для определения методов для типа userdata
  • 58. Функции в Lua Основные элементы • Могут быть вложенными:
  • 59. Функции в Lua Основные элементы • Могут быть вложенными: function foo(n) -- global function local var = function(m) -- function in var return m + n -- n is from `foo` end local function bar() -- another form of var return var(2) end return bar() end
  • 60. Функции в Lua Основные элементы • Могут быть вложенными: function foo(n) -- global function local var = function(m) -- function in var return m + n -- n is from `foo` end local function bar() -- another form of var return var(2) end return bar() end • Могут быть аргументами и возвращаться из функций:
  • 61. Функции в Lua Основные элементы • Могут быть вложенными: function foo(n) -- global function local var = function(m) -- function in var return m + n -- n is from `foo` end local function bar() -- another form of var return var(2) end return bar() end local function f(cb) -- accepts callback function return function(args) -- accepts some args return cb(args) -- return callback function from args (decorator like) end end • Могут быть аргументами и возвращаться из функций:
  • 62. Функции в Lua Замыкания function test(n) local f = function() return n + 1 -- n is captured end n = n + 1 -- n in f is also modified return а end test(1) -- Returns function closure test(1)() -- Returns 3
  • 63. Функции в Lua Замыкания function test(n) local f = function() return n + 1 -- n is captured end n = n + 1 -- n in f is also modified return а end test(1) -- Returns function closure test(1)() -- Returns 3 Замыкание
  • 64. Функции в Lua Замыкания function test(n) local f = function() return n + 1 -- n is captured end n = n + 1 -- n in f is also modified return а end test(1) -- Returns function closure test(1)() -- Returns 3 Замыкание
  • 65. Функции в Lua Замыкания function test(n) local f = function() return n + 1 -- n is captured end n = n + 1 -- n in f is also modified return а end test(1) -- Returns function closure test(1)() -- Returns 3 Замыкание Переменные входят по ссылке
  • 66. Функции в Lua Замыкания function test(n) local f = function() return n + 1 -- n is captured end n = n + 1 -- n in f is also modified return а end test(1) -- Returns function closure test(1)() -- Returns 3 Замыкание Переменные входят по ссылке Можно возвращать функцию
  • 67. Функции в Lua Замыкания function test(n) local f = function() return n + 1 -- n is captured end n = n + 1 -- n in f is also modified return а end test(1) -- Returns function closure test(1)() -- Returns 3 Замыкание Переменные входят по ссылке Функция-замыкание Можно возвращать функцию
  • 68. Функции в Lua Замыкания function test(n) local f = function() return n + 1 -- n is captured end n = n + 1 -- n in f is also modified return а end test(1) -- Returns function closure test(1)() -- Returns 3 Замыкание Переменные входят по ссылке Функция-замыкание Непосредственно вызов Можно возвращать функцию
  • 69. Функции в Lua • Позволяют писать в функциональном стиле (библиотека lua-fun) • Замыкания работают также для C функций • Передача по ссылке несколько необычна, но эффективна • Время жизни замыкания ассоциируется с переменной, в которой оно хранится
  • 71. Строки в Lua Передача строки из C Глобальный хеш строк s1 s2 s3 lua_pushstring (L, "hello"); hello Копия Хеш hash(hello) Поиск
  • 72. Строки в Lua Передача строки из C Глобальный хеш строк s1 s2 s3 lua_pushstring (L, "hello"); hello Вставка hello
  • 73. Строки в Lua • Строки в Lua неизменяемы • Сравнение строк - просто сравнение указателей: O(1) • Создание и передача строк - дорогая операция • Если нужно делать строку из кусков, то нужно использовать таблицу и table.concat
  • 75. Строки в Lua Передача текста C C Userdata const char *s size_t len refcounter
  • 80. Виртуальный стек Вызов функции 1 2 3 4 -3 -2 -1 5 6 Внутренние переменые number string 4 5 -2 -1 Аргументы Возвращаемые значения
  • 82. Проблемы работы со стеком • Скорость: переключение занимает около сотни CPU cycles
  • 83. Проблемы работы со стеком • Скорость: переключение занимает около сотни CPU cycles • Проблемы контроля: без специальных ключей компиляции легко получить низкоуровневые ошибки (вплоть до полного падения)
  • 84. Проблемы работы со стеком • Скорость: переключение занимает около сотни CPU cycles • Проблемы контроля: без специальных ключей компиляции легко получить низкоуровневые ошибки (вплоть до полного падения)
  • 85. Проблемы работы со стеком • Скорость: переключение занимает около сотни CPU cycles • Проблемы контроля: без специальных ключей компиляции легко получить низкоуровневые ошибки (вплоть до полного падения) • Крайне неочевидный код
  • 86. Проблемы работы со стеком • Скорость: переключение занимает около сотни CPU cycles • Проблемы контроля: без специальных ключей компиляции легко получить низкоуровневые ошибки (вплоть до полного падения) • Крайне неочевидный код • Есть ряд сложных моментов (итерация по таблице)
  • 87. Пример из практики Итерация по таблице lua_pushvalue (L, i); /* Push table on top */ lua_pushnil (L); /* Push nil to start iterate */ while (lua_next (L, -2)) { lua_pushvalue (L, -2); /* Copy key as it is special */ key = luaL_checkstring (L, -1); value = luaL_checkstring (L, -2); lua_pop (L, 2); /* Remove key and value leaving original key */ } lua_pop (L, 1); /* Remove table */
  • 88. Пример из практики Итерация по таблице lua_pushvalue (L, i); tabletop -1
  • 89. Пример из практики Итерация по таблице lua_pushvalue (L, i); lua_pushnil (L); tabletop -2 nil -1
  • 90. Пример из практики Итерация по таблице table -2 nil -1 while (lua_next (L, -2)) table -3 key -2 value -1 Предыдущий ключ Новый ключ
  • 91. Пример из практики Итерация по таблице lua_pushvalue (L, -2); key = luaL_checkstring (L, -1); value = luaL_checkstring (L, -2); table -2 key -1 value key copy -3 -4
  • 92. Пример из практики Итерация по таблице lua_pop (L, 2); table -2 key -1 value key copy -3 -4 table key -1 -2 while (lua_next (L, -2)) Используется для следующей итерации
  • 94. Плюсы FFI • Очень быстро работают для простых типов (десяток циклов) • Поддерживают все конструкции C99 • Поддерживают типы-обертки (boxed types), например 64-х битные целые • Проще поддерживать
  • 95. FFI вызовы Синтетические тесты Секунды(меньше-лучше) 0 10 20 30 40 tanh(x) strcmp(s1, s2) Plain call FFI Plain call FFI 5.97c 3.13c 4.38c 30.07c 10x
  • 96. Пример из практики Оптимизация узких мест local ffi if type(jit) == 'table' then ffi = require("ffi") ffi.cdef[[ int rspamd_re_cache_type_from_string (const char *str); int rspamd_re_cache_process_ffi (void *ptask, void *pre, int type, const char *type_data, int is_strong); ]] end local function process_regexp_opt(re, task, re_type, header, strong) if type(jit) == 'table' then -- Use ffi call local itype = ffi.C.rspamd_re_cache_type_from_string(re_type) if not strong then strong = 0 else string = 1 end local iret = ffi.C.rspamd_re_cache_process_ffi (task, re, itype, header, strong) return tonumber(iret) else return task:process_regexp(re, re_type, header, strong) end end Проверка LuaJIT
  • 97. local ffi if type(jit) == 'table' then ffi = require("ffi") ffi.cdef[[ int rspamd_re_cache_type_from_string (const char *str); int rspamd_re_cache_process_ffi (void *ptask, void *pre, int type, const char *type_data, int is_strong); ]] end local function process_regexp_opt(re, task, re_type, header, strong) if type(jit) == 'table' then -- Use ffi call local itype = ffi.C.rspamd_re_cache_type_from_string(re_type) if not strong then strong = 0 else string = 1 end local iret = ffi.C.rspamd_re_cache_process_ffi (task, re, itype, header, strong) return tonumber(iret) else return task:process_regexp(re, re_type, header, strong) end end Определение С функций Пример из практики Оптимизация узких мест
  • 98. local ffi if type(jit) == 'table' then ffi = require("ffi") ffi.cdef[[ int rspamd_re_cache_type_from_string (const char *str); int rspamd_re_cache_process_ffi (void *ptask, void *pre, int type, const char *type_data, int is_strong); ]] end local function process_regexp_opt(re, task, re_type, header, strong) if type(jit) == 'table' then -- Use ffi call local itype = ffi.C.rspamd_re_cache_type_from_string(re_type) if not strong then strong = 0 else string = 1 end local iret = ffi.C.rspamd_re_cache_process_ffi (task, re, itype, header, strong) return tonumber(iret) else return task:process_regexp(re, re_type, header, strong) end end FFI call Userdata to C pointer bool -> int Пример из практики Оптимизация узких мест
  • 99. local ffi if type(jit) == 'table' then ffi = require("ffi") ffi.cdef[[ int rspamd_re_cache_type_from_string (const char *str); int rspamd_re_cache_process_ffi (void *ptask, void *pre, int type, const char *type_data, int is_strong); ]] end local function process_regexp_opt(re, task, re_type, header, strong) if type(jit) == 'table' then -- Use ffi call local itype = ffi.C.rspamd_re_cache_type_from_string(re_type) if not strong then strong = 0 else string = 1 end local iret = ffi.C.rspamd_re_cache_process_ffi (task, re, itype, header, strong) return tonumber(iret) else return task:process_regexp(re, re_type, header, strong) end end Plain call Пример из практики Оптимизация узких мест
  • 100. Оптимизация FFI вызовов Lua вызов FFI вызов
  • 102. Проблемы FFI • Поддерживаются на ограниченном количестве архитектур (Sparc64)
  • 103. Проблемы FFI • Поддерживаются на ограниченном количестве архитектур (Sparc64) • В plain Lua требуют отдельного модуля FFI, LuaJIT поддерживает “из коробки”
  • 104. Проблемы FFI • Поддерживаются на ограниченном количестве архитектур (Sparc64) • В plain Lua требуют отдельного модуля FFI, LuaJIT поддерживает “из коробки” • Нет проверки типов, нет контроля целостности памяти
  • 105. Проблемы FFI • Поддерживаются на ограниченном количестве архитектур (Sparc64) • В plain Lua требуют отдельного модуля FFI, LuaJIT поддерживает “из коробки” • Нет проверки типов, нет контроля целостности памяти
  • 106. Проблемы FFI • Поддерживаются на ограниченном количестве архитектур (Sparc64) • В plain Lua требуют отдельного модуля FFI, LuaJIT поддерживает “из коробки” • Нет проверки типов, нет контроля целостности памяти
  • 107. Проблемы FFI • Поддерживаются на ограниченном количестве архитектур (Sparc64) • В plain Lua требуют отдельного модуля FFI, LuaJIT поддерживает “из коробки” • Нет проверки типов, нет контроля целостности памяти • Не всегда быстрее
  • 108. Проблемы FFI • Поддерживаются на ограниченном количестве архитектур (Sparc64) • В plain Lua требуют отдельного модуля FFI, LuaJIT поддерживает “из коробки” • Нет проверки типов, нет контроля целостности памяти • Не всегда быстрее • Очень сложно сделать sandbox
  • 111. Выводы • Lua простой для изучения
  • 112. Выводы • Lua простой для изучения
  • 113. Выводы • Lua простой для изучения • Lua удобен для встраивания
  • 114. Выводы • Lua простой для изучения • Lua удобен для встраивания
  • 118. Выводы • Основной инструмент - таблицы • Основной инструмент - функции
  • 119. Выводы • Основной инструмент - таблицы • Основной инструмент - функции
  • 121. Выводы • Lua - быстрый язык (особенно LuaJIT)
  • 122. Выводы • Lua - быстрый язык (особенно LuaJIT)
  • 123. Выводы • Lua - быстрый язык (особенно LuaJIT) • Некоторые оптимизации бывают опасны
  • 124. Выводы • Lua - быстрый язык (особенно LuaJIT) • Некоторые оптимизации бывают опасны