Skip to content

Instantly share code, notes, and snippets.

@timcharper
Created March 20, 2018 03:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save timcharper/2771c2d6c53afa05eb7b6eafc406e0d2 to your computer and use it in GitHub Desktop.
Save timcharper/2771c2d6c53afa05eb7b6eafc406e0d2 to your computer and use it in GitHub Desktop.
OrientDB simple delete benchmark
{"op": "removing each vertex one at a time", "secs": 5.85228219}
{"op": "method 1", "secs": 5.87633618}
{"op": "removing edges first", "secs": 31.594552465}
{"op": "removing each vertex one at a time", "secs": 0.48545163}
{"op": "method 2", "secs": 32.106060129}
{"op": "remove edges via sql", "secs": 2.645357744}
{"op": "remove vertices via direct delete sql", "secs": 6.376951457}
{"op": "method 3", "secs": 9.050751531}
{"op": "remove vertices via direct sql", "secs": 11.447992113}
{"op": "method 4", "secs": 11.475689888}
{"op": "remove edges via sql", "secs": 2.097860989}
{"op": "removing each vertex one at a time", "secs": 6.283697866}
{"op": "method 5", "secs": 8.406108997}
import $ivy.`com.orientechnologies:orientdb-graphdb:2.2.24`
import ammonite.ops._
import com.tinkerpop.blueprints._
import com.tinkerpop.blueprints.impls.orient._
import scala.collection.JavaConverters._
import java.time.Instant
import com.orientechnologies.orient.core.sql.OCommandSQL
case class Number(value: Int, odd: Boolean, timestamp: Instant)
def openGraph(name: String): OrientBaseGraph = {
mkdir(pwd / 'target)
val factory = new OrientGraphFactory(s"plocal:${pwd}/target/${name}").setupPool(1,10)
val graph = factory.getNoTx()
graph
}
def addNumber(graph: OrientBaseGraph, number: Number): Vertex = {
val v = graph.addVertex("class:Number", Nil:_*)
v.setProperty("value", number.value)
v.setProperty("odd", number.odd)
v.setProperty("timestamp", number.timestamp)
v
}
def divisors(i: Int): Seq[Int] = {
(1 until i).filter { n => i % n == 0 }.toSeq
}
def benchmark[T](wat: String)(body: => T): T = {
val start = System.nanoTime
try {
body
} finally {
val duration = System.nanoTime - start
println(s"""{"op": "${wat}", "secs": ${duration.toDouble / 1000000000}}""")
}
}
val numbers = (1 to 10000).map { n => Number(n, n % 2 == 1, Instant.now) }
def populate(graph: OrientBaseGraph): (Seq[Vertex], Seq[Edge]) = {
val numberClass = graph.createVertexType("Number")
val edgeClass = graph.createEdgeType("Divisor")
val vertices = benchmark("adding vertices") { numbers.map(addNumber(graph, _)) }
val edges = benchmark("adding edges") {
for {
(v, i) <- vertices.zipWithIndex
divisor <- divisors(i)
divisorV = vertices(divisor)
} yield {
v.addEdge("class:Divisor", divisorV)
}
}
(vertices, edges)
}
def setup(graph: OrientBaseGraph): (Seq[Vertex], Seq[Edge]) = {
(
graph.getVertices().asScala.toSeq,
graph.getEdges().asScala.toSeq)
}
def bmMethod1(graph: OrientBaseGraph): Unit = {
val (vertices, edges) = setup(graph)
benchmark("removing each vertex one at a time") { graph.getVertices.asScala.foreach { _.remove } }
}
def bmMethod2(graph: OrientBaseGraph): Unit = {
val (vertices, edges) = setup(graph)
benchmark("removing edges first") { graph.getEdges.asScala.foreach { _.remove } }
benchmark("removing each vertex one at a time") { graph.getVertices.asScala.foreach { _.remove } }
}
def bmMethod3(graph: OrientBaseGraph): Unit = {
val (vertices, edges) = setup(graph)
benchmark("remove edges via sql") {
val edgesList = edges.map(_.getId.toString).mkString(",")
graph.command(new OCommandSQL(s"DELETE FROM Divisor where @rid IN [${edgesList}] UNSAFE")).execute[Int]()
// graph.command(new OCommandSQL(s"DELETE EDGE [${edgesList}] BATCH 1000")).execute[Int]()
}
benchmark("remove vertices via direct delete sql") {
val ids = vertices.map(_.getId.toString).mkString(",")
graph.command(new OCommandSQL(s"DELETE FROM Number where @rid IN [${ids}] UNSAFE")).execute[Int]()
}
}
def bmMethod4(graph: OrientBaseGraph): Unit = {
val (vertices, edges) = setup(graph)
benchmark("remove vertices via direct sql") {
val ids = vertices.map(_.getId.toString).mkString(",")
graph.command(new OCommandSQL(s"DELETE VERTEX Number WHERE @rid IN [$ids]")).execute[Int]()
}
}
// graph.command(new OCommandSQL("SELECT * FROM Number WHERE odd = true")).execute[java.lang.Iterable[Vertex]]().asScala
def bmMethod5(graph: OrientBaseGraph): Unit = {
val (vertices, edges) = setup(graph)
benchmark("remove edges via sql") {
val edgesList = edges.map(_.getId.toString).mkString(",")
graph.command(new OCommandSQL(s"DELETE FROM Divisor where @rid IN [${edgesList}] UNSAFE")).execute[Int]()
}
benchmark("removing each vertex one at a time") { graph.getVertices.asScala.foreach { _.remove } }
}
@main def setup(): Unit = {
val graph = openGraph(s"template")
val (vertices, edges) = populate(graph)
graph.shutdown()
implicit val wd = pwd
%("tar", "zcf", "template.tgz", "target/template")
}
@main def run(idx: Int): Unit = {
implicit val wd = pwd
rm!(pwd / 'target)
%("tar", "xzf", "template.tgz")
val methods: Map[Int, OrientBaseGraph => Unit] = Map(
1 -> (bmMethod1(_: OrientBaseGraph)),
2 -> (bmMethod2(_: OrientBaseGraph)),
3 -> (bmMethod3(_: OrientBaseGraph)),
4 -> (bmMethod4(_: OrientBaseGraph)),
5 -> (bmMethod5(_: OrientBaseGraph)))
val graph = openGraph("template")
try {
benchmark(s"method ${idx}") { methods(idx)(graph) }
} finally graph.shutdown()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment