Балуюсь с запросами
Jan 4, 2017
3 minutes read

Отвелекусь немного на сами данные. Сейчас отношения примитивно и неоптимально со всех точек зрения. Пока я предполагаю что весь state (и persistent и transient) будет валятся в таких структурах. Хочется проверить насколько это все реально, соответственно хочу померить уже известную мне dbmonster модель. Захуярю-ка я ее в “базу”.

В datomic (или RDF-alike) модель запихать монстра оказалось даже быстрее чем в объекты конкретных классов: вот весь код создания базы:

const
  DatabaseName = A(1)
  Elapsed = A(2)
  Waiting = A(3)
  SQL = A(4)
  Queries = A(5)

proc genQuery(db: DB): E =
  result = getId()
  db.add(result, Elapsed, random(1500))
  db.add(result, Waiting, random(2) == 0)
  var query: string
  case random(10)
  of 0: query = "vacuum"
  of 1..2: query = "<IDLE> in transaction"
  else: query = "SELECT blah FROM something"
  db.add(result, SQL, query)
  
proc genDatabase(db: DB, name: string): E =
  result = getId()
  db.add(result, DatabaseName, name)
  for i in 0..random(10):       
    db.add(result, Queries, db.genQuery())

proc getData*(): Db =
  result = newDB([sizeof E, sizeof A, -1], [Order(0x123)])
  for i in 1..ROWS:
    discard result.genDatabase("cluster" & $i)
    discard result.genDatabase("cluster" & $i & " slave")

Запускаем, и видим ожидаемую жопу: 1.8ms на генерацию для 200 монстробаз. Это нативно. Напомню что оригинал генерировал данные за 0.36ms нативно. Интересно, что уменьшая количество данных в 2 раза, время построения уменьшается линейно до 0.9ms, что говорит о том что неэффктивность где-то в сериализации тупла, а не в уебищной структуре данных (можно было ожидать что тормозит вставка с сортировкой, но походу нет).

Пробую V8. Оригинал – 1ms. “База данных” – полная сракотень 18.9ms. С другой стороны, на V8 уменьшив объем данных в 10 раз получаю ускорение в 20 раз, до 0.8ms. Что нам это говорит? Видимо то что emscripten и движки JS пока далеки от генерации чего-то похожего на нативный код. Думаю что memcpy реализован циклом по массиву HEAP… Или чота типа того. Safari как всегда впереди всех - 14.7ms но тоже не торт. Возможно корень зла в emscripten и webassembly отожгет.

Ладно, хер с ним переживать - все это можно оптимизировать в разы. Продолжу с сутью и давайте попробуем выбрать все запросы где Waiting == true. Для этого добавлю AVE индекс: var monster = newDB([sizeof E, sizeof A, -1], [Order(0x123), Order(0x231)])

Ха-ха-Ха ебать, и вот она - пизда! 10ms на итерацию в нативном коде. Ну конечно, идентификаторы триплов я генерировал последовательно, и они (триплы) добавлялись в конец, а с индексом понеслась пизда по кочкам, все таки структура данных (тупо массив) - откровенное гавно, но это меня не остановит.

  var q = newQuery()
  q.pred(monster, variable("?e"), constant(Waiting), constant(true))
  q.select("?e")
  q.prepare
  q.execute

ОК, соснул, построились кривые итераторы не из того места… Починил, включая поддержку 32 бит. Осталось поправить багу (iter.up/iter.open должен перематывать итератор в начало), но бага мешает толко для “плохих” планов (так то нехуй ничо перематывать).

А вот с запросами двигло работет побыстрее. Поиск монстробаз где Waiting == true5.5ms на V8:

  q.pred(monster, variable("?q"), constant(Waiting), constant(true))
  q.pred(monster, variable("?db"), constant(Queries), variable("?q"))
  q.pred(monster, variable("?db"), constant(DatabaseName), variable("?name"))
  q.select("?name")
  q.prepare
  q.execute

На сегодня с программированием завязал, надо подумать что со всем этим делать дальше. Код под тегом day-170104.


Назад, к записям


comments powered by Disqus