Сохранение и чтение таблиц в файле

Столкнулись с проблемой в использовании макросов? Здесь можно получить помощь.
Post Reply
buniak_a_h
Posts: 352
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 37 times
Been thanked: 5 times
Contact:

Сохранение и чтение таблиц в файле

Post by buniak_a_h » Sun 10 Sep, 2017 23:21

Здравствуйте.
Мне посоветовали (John Doe) хранить таблицы во внешнем файле.Посоветуйте, пожалуйста, как это лучше сделать.

User avatar
John Doe
Бюрократ
Posts: 11217
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 14 times
Been thanked: 80 times

Сохранение и чтение таблиц в файле

Post by John Doe » Mon 11 Sep, 2017 05:55

Однозначно хранить все индексы, и соответственно считывать сразу всё в память не стоит (независимо от того база это или файл).
Остальное надо смотреть, что и где тормозит. Код вы не показали.

Не исключено что база окажется лучшим вариантом.

buniak_a_h
Posts: 352
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 37 times
Been thanked: 5 times
Contact:

Сохранение и чтение таблиц в файле

Post by buniak_a_h » Mon 11 Sep, 2017 08:02

John Doe wrote:
Mon 11 Sep, 2017 05:55
Код вы не показали



buniak_a_h
Posts: 352
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 37 times
Been thanked: 5 times
Contact:

Сохранение и чтение таблиц в файле

Post by buniak_a_h » Mon 11 Sep, 2017 08:17

John Doe wrote:
Mon 11 Sep, 2017 05:55
считывать сразу всё в память не стоит
На самом деле 55000 ключей - это один chm-файл (помощь по языку php). Бинарный поиск по отсортированным ключам быстроходнее, чем перебор; а, значит, надо хранить ВСЕ ключи (хотя бы к одному chm-файлу). Остальные ключи на порядок меньше, поэтому я реально решил хранить все сформированные ключи в памяти и на будущее записывать их в базу. Получилось реально заметно быстрее, чем перебором (поиском) по файлу; тем более, что в таком случае не требуется распаковывать оглавление и индекс.

buniak_a_h
Posts: 352
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 37 times
Been thanked: 5 times
Contact:

Сохранение и чтение таблиц в файле

Post by buniak_a_h » Mon 11 Sep, 2017 08:25

John Doe, пример использования тут: Active-Help ( архив версии 8 )
Last edited by buniak_a_h on Mon 11 Sep, 2017 08:26, edited 2 times in total.

User avatar
John Doe
Бюрократ
Posts: 11217
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 14 times
Been thanked: 80 times

Сохранение и чтение таблиц в файле

Post by John Doe » Mon 11 Sep, 2017 10:07

buniak_a_h wrote:
Mon 11 Sep, 2017 08:17
На самом деле 55000 ключей - это один chm-файл (помощь по языку php).
Неслабо. Интересно сколько памяти съедает загрузить их сразу в одну таблицу.
buniak_a_h wrote:
Mon 11 Sep, 2017 08:17
поэтому я реально решил хранить все сформированные ключи в памяти
В памяти их точно нет смысла хранить, во всяком случае до первого использования.
buniak_a_h wrote:
Mon 11 Sep, 2017 08:17
Какие функции описаны в macroapi_manual.ru.chm, какие - в luafar_manual.chm, а какие - в FarEncyclopedia.ru.chm, я логику понять не могу
Если упростить, то принцип такой.
Таблицы с маленькой буквы это luafar.
Таблицы с Большой буквы это luamacro.
А открывать FarEncyclopedia.ru.chm придётся, только если farmanager.com не доступен.

P.S.
Я не говорю, что искать в нескольких файлах это плохая идея.

P.P.S.
Код ещё не смотрел, отпишусь.
Last edited by John Doe on Mon 11 Sep, 2017 10:10, edited 1 time in total.

User avatar
John Doe
Бюрократ
Posts: 11217
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 14 times
Been thanked: 80 times

Сохранение и чтение таблиц в файле

Post by John Doe » Mon 11 Sep, 2017 10:35

Оптимизированный код - 40 секунд
Вероятно в коде проблема.
Главное что незачем изобретать сериализацию таблиц при наличии проверенных решений, посмотрите например здесь http://lua-users.org/wiki/TableSerialization.

Впрочем, для вашей задачи ничего такого не требуется.
Разве не достаточно сохранять в индексе пары "ключ=значение"?

Code: Select all

file:write(("[%q]=%q"):format(key,value))
А вся остальная информация может в базе лежать, как и раньше.

buniak_a_h
Posts: 352
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 37 times
Been thanked: 5 times
Contact:

Сохранение и чтение таблиц в файле

Post by buniak_a_h » Mon 11 Sep, 2017 12:19

John Doe wrote:
Mon 11 Sep, 2017 11:42
Сразу можно в таком виде составлять.
Ну, на самом деле это - то же самое, о чём я и написал. Т.е. составляется именованная таблица (в Вашем примере - obj). А уже потом (когда конкретно - перед добавлением в общий список или потом - чохом -- это надо по времени смотреть, что шустрее) преобразуется в строки в регулярный массив строк.
Там ещё надо проверять, что быстрее сортируется. Тем более, что для case-unsensitive поиска сортировать надо по lcase(Name). А для точного поиска оставлять исходный Name. И что быстрее - преобразовывать "на ходу" в функции сравнения либо сразу в отдельное поле для сортировки - надо знать алгоритм сортировки. Если пузырьки или простая вставка - точно быстрее завести отдельное поле. 55000! сравнений - это даже посчитать трудно :-)

buniak_a_h
Posts: 352
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 37 times
Been thanked: 5 times
Contact:

Сохранение и чтение таблиц в файле

Post by buniak_a_h » Mon 11 Sep, 2017 13:18

John Doe wrote:
Mon 11 Sep, 2017 10:07
buniak_a_h wrote:
Mon 11 Sep, 2017 08:17
На самом деле 55000 ключей - это один chm-файл (помощь по языку php).
Неслабо. Интересно сколько памяти съедает загрузить их сразу в одну таблицу.
Не знаю. На WinXP x86 SP3 хватает. Т.е. 64-разрядной не требует.
На самом деле там много повторов. Но не фильтровать же! Microsoft так поставляет! Впрочем, я, похоже, где-то ошибся: по моим подсчётам должно быть не 55, а 27 тыщ...

User avatar
John Doe
Бюрократ
Posts: 11217
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 14 times
Been thanked: 80 times

Сохранение и чтение таблиц в файле

Post by John Doe » Mon 11 Sep, 2017 13:30

Конкретный скрипт предлагаю обсуждать в его теме (туда уже переправились пара наших сообщений).

Ну а в контексте сохранения данных в файл, учитывая потребность в сортированном индексе, полагаю можно предложить такой формат записи:

Code: Select all

("  {name=%q,Name=%q,Local=%q},"):format(key:lower(),key,value)

buniak_a_h
Posts: 352
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 37 times
Been thanked: 5 times
Contact:

Сохранение и чтение таблиц в файле

Post by buniak_a_h » Mon 11 Sep, 2017 14:40

John Doe wrote:
Mon 11 Sep, 2017 13:30
Конкретный скрипт предлагаю обсуждать в его теме
Да, эту тему можно уже закрыть. Ответы получены, спасибо.
Хотя :
(а) Вы где-то писали, что хранение таблицы не в символьном виде возможно в lua. Но не написали, как. Вызов file:write() допустим только с символьными или текстовыми параметрами, а указывать tostring(table) - глупо...
(б) Вы также советовали посмотреть исходный код mf.msave. Там есть вызов serialize. Жаль, что она скрыта "внутри". Вытащить-то можно, просто, компилированная работала бы быстрее.Ну, добавить параметр Separator (там забита константа '\n'). Может, это - именно то, что мне нужно... было.

User avatar
John Doe
Бюрократ
Posts: 11217
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 14 times
Been thanked: 80 times

Сохранение и чтение таблиц в файле

Post by John Doe » Mon 11 Sep, 2017 15:46

buniak_a_h wrote:
Mon 11 Sep, 2017 14:40
(а) Вы где-то писали, что хранение таблицы не в символьном виде возможно в lua. Но не написали, как. Вызов file:write() допустим только с символьными или текстовыми параметрами, а указывать tostring(table) - глупо...
Строка это тип данных в луа, совсем не обязательно предполагающий текст (читаемый, разбитый на строки, и т.п.).
Таблицу выгрузить можно только сериализовав в строку.
buniak_a_h wrote:
Mon 11 Sep, 2017 14:40
(б) Вы также советовали посмотреть исходный код mf.msave. Там есть вызов serialize. Жаль, что она скрыта "внутри". Вытащить-то можно, просто, компилированная работала бы быстрее.Ну, добавить параметр Separator (там забита константа '\n'). Может, это - именно то, что мне нужно... было.
"Компилированными" функции, определённые в lua-файлах не являются.
luajit всё скомпилирует когда надо, что вашу функцию, что содержимое api.lua.

Помимо msave я давал ссылку на другие реализации.
Знать полезно, но как я уже говорил, для вашей задачи просто избыточно, как из пушки по воробьям.

buniak_a_h
Posts: 352
Joined: Sat 20 Apr, 2013 00:17
Location: Питер
Has thanked: 37 times
Been thanked: 5 times
Contact:

Сохранение и чтение таблиц в файле

Post by buniak_a_h » Mon 11 Sep, 2017 16:32

John Doe wrote:
Mon 11 Sep, 2017 15:46
luajit всё скомпилирует когда надо, что вашу функцию, что содержимое api.lua.
Чо-т я был уверен, что lua, используемый в макро, - интерпретируемые функции. Ну, максимум в "шитый код" преобразуются.
John Doe wrote:
Mon 11 Sep, 2017 15:46
избыточно, как из пушки по воробьям.
1. Как пример интересно.
2. Никогда не знаешь, что пригодится...

User avatar
John Doe
Бюрократ
Posts: 11217
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 14 times
Been thanked: 80 times

Сохранение и чтение таблиц в файле

Post by John Doe » Mon 11 Sep, 2017 16:48

buniak_a_h wrote:
Mon 11 Sep, 2017 16:32
Чо-т я был уверен, что lua, используемый в макро, - интерпретируемые функции. Ну, максимум в "шитый код" преобразуются.
Во что бы они не преобразовывались, код макросов, и код самого плагина (luamacro) тут равноправны.
buniak_a_h wrote:
Mon 11 Sep, 2017 16:32
1. Как пример интересно.
Безусловно.

User avatar
zg
zero-gravity
Posts: 5262
Joined: Tue 15 Mar, 2005 17:36
Location: riga
Been thanked: 43 times
Contact:

Сохранение и чтение таблиц в файле

Post by zg » Tue 12 Sep, 2017 11:51

Code: Select all

local function LongTableToString(arr, sSep)
  local res={}
  local convert=function(name,value)
    local vtype=type(value)
    if vtype=='number' or vtype=='string' or vtype=='boolean' or vtype=='table' then
      if vtype=='string' then
        value=string.format('%q',value)
      elseif vtype=='table' then
        value=LongTableToString(value,sSep)
      else
        value=tostring(value)
      end
      if name then value=name..'='..value end
      table.insert(res,value)
    end
  end
  for _,v in ipairs(arr) do convert(false,v) end
  for i,v in pairs(arr) do if type(i)~='number' then convert(i,v) end end
  return '{\n'..table.concat(res,sSep)..'\n}'
end

Post Reply

Return to “Нужна помощь”