From 40211ad6cf1e2072480f47e217a51581d08ad348 Mon Sep 17 00:00:00 2001
From: Pawan Rawal <pawan0201@gmail.com>
Date: Sat, 14 May 2016 12:59:00 +0530
Subject: [PATCH] Optimizations and refactoring

1. Changing extension of files with binary data to .bin.
2. Running separate benchmark for each query according to numElements in their
result.
---
 query/benchmark/README.txt                    |  21 ++++++----
 .../benchmark/{actors10.txt => actors10.bin}  | Bin
 .../{actors100.txt => actors100.bin}          | Bin
 .../{actors1000.txt => actors1000.bin}        | Bin
 .../{directors10.txt => directors10.bin}      | Bin
 .../{directors100.txt => directors100.bin}    | Bin
 .../{directors1000.txt => directors1000.bin}  | Bin
 query/query.go                                |  17 ++++-----
 query/query_test.go                           |  36 ++++++++----------
 server/main.go                                |   8 ++--
 10 files changed, 39 insertions(+), 43 deletions(-)
 rename query/benchmark/{actors10.txt => actors10.bin} (100%)
 rename query/benchmark/{actors100.txt => actors100.bin} (100%)
 rename query/benchmark/{actors1000.txt => actors1000.bin} (100%)
 rename query/benchmark/{directors10.txt => directors10.bin} (100%)
 rename query/benchmark/{directors100.txt => directors100.bin} (100%)
 rename query/benchmark/{directors1000.txt => directors1000.bin} (100%)

diff --git a/query/benchmark/README.txt b/query/benchmark/README.txt
index d70e0e11..284e79e8 100644
--- a/query/benchmark/README.txt
+++ b/query/benchmark/README.txt
@@ -26,17 +26,22 @@ Directors query
     }
 }
 
+14 May 2016
 Benchmarking tests were run for ToJson and ToProtocolBuffer methods. Results
 from the `go test` command are tabulated below.
 
-BenchmarkToJson                500       3583970 ns/op      957747 B/op      16115 allocs/op
-BenchmarkToProtocolBuffer     1000       2299409 ns/op      566288 B/op       7542 allocs/op
+BenchmarkToJSON_10_Actor         20000       92797 ns/op     22616 B/op      319 allocs/op
+BenchmarkToJSON_10_Director      20000       87246 ns/op     21111 B/op      303 allocs/op
+BenchmarkToJSON_100_Actor         2000      774767 ns/op    207893 B/op     2670 allocs/op
+BenchmarkToJSON_100_Director      2000      579467 ns/op    142811 B/op     2103 allocs/op
+BenchmarkToJSON_1000_Actor         200     7903001 ns/op   1904863 B/op    24712 allocs/op
+BenchmarkToJSON_1000_Director      300     4335375 ns/op    957728 B/op    16115 allocs/op
+BenchmarkToPB_10_Actor          100000       19672 ns/op      3176 B/op       60 allocs/op
+BenchmarkToPB_10_Director       100000       17891 ns/op      3096 B/op       60 allocs/op
+BenchmarkToPB_100_Actor          10000      372288 ns/op     30728 B/op      556 allocs/op
+BenchmarkToPB_100_Director        5000      221506 ns/op     37272 B/op      701 allocs/op
+BenchmarkToPB_1000_Actor           500     2612757 ns/op    296486 B/op     5383 allocs/op
+BenchmarkToPB_1000_Director        300     3980677 ns/op    395600 B/op     7376 allocs/op
 
 We can see that ToProtocolBuffer method allocates less memory and takes lesser
 time than ToJson method.
-
-After changing properties inside a graph.Node from a map to a slice, we can see
-further improvements.
-
-BenchmarkToJson                500       3726982 ns/op      957679 B/op      16115 allocs/op
-BenchmarkToProtocolBuffer     1000       1954618 ns/op      395603 B/op       7377 allocs/op
diff --git a/query/benchmark/actors10.txt b/query/benchmark/actors10.bin
similarity index 100%
rename from query/benchmark/actors10.txt
rename to query/benchmark/actors10.bin
diff --git a/query/benchmark/actors100.txt b/query/benchmark/actors100.bin
similarity index 100%
rename from query/benchmark/actors100.txt
rename to query/benchmark/actors100.bin
diff --git a/query/benchmark/actors1000.txt b/query/benchmark/actors1000.bin
similarity index 100%
rename from query/benchmark/actors1000.txt
rename to query/benchmark/actors1000.bin
diff --git a/query/benchmark/directors10.txt b/query/benchmark/directors10.bin
similarity index 100%
rename from query/benchmark/directors10.txt
rename to query/benchmark/directors10.bin
diff --git a/query/benchmark/directors100.txt b/query/benchmark/directors100.bin
similarity index 100%
rename from query/benchmark/directors100.txt
rename to query/benchmark/directors100.bin
diff --git a/query/benchmark/directors1000.txt b/query/benchmark/directors1000.bin
similarity index 100%
rename from query/benchmark/directors1000.txt
rename to query/benchmark/directors1000.bin
diff --git a/query/query.go b/query/query.go
index 64234638..6eeaece7 100644
--- a/query/query.go
+++ b/query/query.go
@@ -338,17 +338,14 @@ func (g *SubGraph) preTraverse(uid uint64, dst *graph.Node) error {
 			}
 
 			v.Str = ival.(string)
-			properties = append(properties,
-				&graph.Property{Prop: pc.Attr, Val: v})
-		}
-	}
 
-	for i, p := range properties {
-		if p.Prop == "_xid_" {
-			dst.Xid = p.Val.Str
-			// Deleting the _xid_ property if it exists
-			properties = append(properties[:i], properties[i+1:]...)
-			break
+			if pc.Attr == "_xid_" {
+				dst.Xid = v.Str
+			} else {
+				p := &graph.Property{Prop: pc.Attr, Val: v}
+				properties = append(properties, p)
+			}
+
 		}
 	}
 	dst.Properties, dst.Children = properties, children
diff --git a/query/query_test.go b/query/query_test.go
index 7f1b41fc..2ddbf7eb 100644
--- a/query/query_test.go
+++ b/query/query_test.go
@@ -326,16 +326,16 @@ func TestToJson(t *testing.T) {
 	fmt.Printf(string(js))
 }
 
-func getProperty(properties []*graph.Property, prop string) (v *graph.Value) {
+func getProperty(properties []*graph.Property, prop string) *graph.Value {
 	for _, p := range properties {
 		if p.Prop == prop {
 			return p.Val
 		}
 	}
-	return v
+	return nil
 }
 
-func TestToProtocolBuffer(t *testing.T) {
+func TestToPB(t *testing.T) {
 	dir, _ := populateGraph(t)
 	defer os.RemoveAll(dir)
 
@@ -458,16 +458,14 @@ func benchmarkToJson(file string, b *testing.B) {
 	}
 }
 
-func BenchmarkToJson(b *testing.B) {
-	benchmarkToJson("benchmark/actors10.txt", b)
-	benchmarkToJson("benchmark/actors100.txt", b)
-	benchmarkToJson("benchmark/actors1000.txt", b)
-	benchmarkToJson("benchmark/directors10.txt", b)
-	benchmarkToJson("benchmark/directors100.txt", b)
-	benchmarkToJson("benchmark/directors1000.txt", b)
-}
+func BenchmarkToJSON_10_Actor(b *testing.B)      { benchmarkToJson("benchmark/actors10.bin", b) }
+func BenchmarkToJSON_10_Director(b *testing.B)   { benchmarkToJson("benchmark/directors10.bin", b) }
+func BenchmarkToJSON_100_Actor(b *testing.B)     { benchmarkToJson("benchmark/actors100.bin", b) }
+func BenchmarkToJSON_100_Director(b *testing.B)  { benchmarkToJson("benchmark/directors100.bin", b) }
+func BenchmarkToJSON_1000_Actor(b *testing.B)    { benchmarkToJson("benchmark/actors1000.bin", b) }
+func BenchmarkToJSON_1000_Director(b *testing.B) { benchmarkToJson("benchmark/directors1000.bin", b) }
 
-func benchmarkToProtocolBuffer(file string, b *testing.B) {
+func benchmarkToPB(file string, b *testing.B) {
 	b.ReportAllocs()
 	var sg SubGraph
 	var l Latency
@@ -492,11 +490,9 @@ func benchmarkToProtocolBuffer(file string, b *testing.B) {
 	}
 }
 
-func BenchmarkToProtocolBuffer(b *testing.B) {
-	benchmarkToProtocolBuffer("benchmark/actors10.txt", b)
-	benchmarkToProtocolBuffer("benchmark/actors100.txt", b)
-	benchmarkToProtocolBuffer("benchmark/actors1000.txt", b)
-	benchmarkToProtocolBuffer("benchmark/directors10.txt", b)
-	benchmarkToProtocolBuffer("benchmark/directors100.txt", b)
-	benchmarkToProtocolBuffer("benchmark/directors1000.txt", b)
-}
+func BenchmarkToPB_10_Actor(b *testing.B)      { benchmarkToPB("benchmark/actors10.bin", b) }
+func BenchmarkToPB_10_Director(b *testing.B)   { benchmarkToPB("benchmark/directors10.bin", b) }
+func BenchmarkToPB_100_Actor(b *testing.B)     { benchmarkToPB("benchmark/actors100.bin", b) }
+func BenchmarkToPB_100_Director(b *testing.B)  { benchmarkToPB("benchmark/directors100.bin", b) }
+func BenchmarkToPB_1000_Actor(b *testing.B)    { benchmarkToPB("benchmark/actors1000.bin", b) }
+func BenchmarkToPB_1000_Director(b *testing.B) { benchmarkToPB("benchmark/directors1000.bin", b) }
diff --git a/server/main.go b/server/main.go
index ea606ee0..c05c2e6b 100644
--- a/server/main.go
+++ b/server/main.go
@@ -209,10 +209,7 @@ type server struct{}
 // This method is used to execute the query and return the response to the
 // client as a protocol buffer message.
 func (s *server) Query(ctx context.Context,
-	req *graph.Request) (*graph.Response, error) {
-	node := new(graph.Node)
-	gl := new(graph.Latency)
-	resp := new(graph.Response)
+	req *graph.Request) (resp *graph.Response, err error) {
 	if len(req.Query) == 0 {
 		glog.Error("While reading query")
 		return resp, fmt.Errorf("Empty query")
@@ -247,13 +244,14 @@ func (s *server) Query(ctx context.Context,
 	l.Processing = time.Since(l.Start) - l.Parsing
 	glog.WithField("q", req.Query).Debug("Graph processed.")
 
-	node, err = sg.ToProtocolBuffer(&l)
+	node, err := sg.ToProtocolBuffer(&l)
 	if err != nil {
 		x.Err(glog, err).Error("While converting to protocol buffer.")
 		return resp, err
 	}
 	resp.N = node
 
+	gl := new(graph.Latency)
 	gl.Parsing, gl.Processing, gl.Pb = l.Parsing.String(), l.Processing.String(),
 		l.ProtocolBuffer.String()
 	resp.L = gl
-- 
GitLab