-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Benchmark event with CBOR encode/decode, checksum
Signed-off-by: tobiasmo1 <[email protected]>
- Loading branch information
0 parents
commit 34c5cbd
Showing
11 changed files
with
307 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.idea | ||
cmd/cmd | ||
cmd/go_build_main_go |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# event-bench | ||
1.) Clone repo locally | ||
|
||
2.) `cd cmd` | ||
|
||
3.) `go build` | ||
|
||
4.) There are two ways to execute the program. To benchmark events generated without a binary value, simply call `./cmd`. | ||
To generate a checksum for an event with a binary value, call `./cmd -b` | ||
|
||
5.) Additional parameters: | ||
|
||
param | type | description | ||
======|======|======================== | ||
-i | int64 | Perform a number of iterations. | ||
-b | bool | True = Generate binary events. False = Generate simple events. | ||
-s | bool | True = When generating binary events, use 100kb image. False = 900kb image. | ||
-p | bool | True = Print the encoded/decoded data. | ||
-c | bool | True = Use contract client form of CBOR encoder/decoder. False = DSDK method/style. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
package main | ||
|
||
import ( | ||
"bufio" | ||
"bytes" | ||
"crypto/sha256" | ||
"flag" | ||
"fmt" | ||
"io" | ||
"log" | ||
"os" | ||
"time" | ||
|
||
"github.com/edgexfoundry/go-mod-core-contracts/models" | ||
"github.com/tobiasmo1/event-bench/events" | ||
"github.com/ugorji/go/codec" | ||
) | ||
|
||
func main() { | ||
var print bool | ||
var useBinary bool | ||
var coredataCBOR bool | ||
var smallPayload bool | ||
var iterations int64 | ||
|
||
flag.BoolVar(&print, "p", true, "Print encoded event, checksum, decoded values to stdout") | ||
flag.BoolVar(&useBinary, "b", false, "Create event with binary payload") | ||
flag.BoolVar(&smallPayload, "s", false, "When creating event use payload bytes of 100k (true) or 900k (false)") | ||
flag.Int64Var(&iterations, "i", 5000, "Sequential iterations (for timing)") | ||
flag.BoolVar(&coredataCBOR, "c", false, "Encode with method patterned after core-data (false = dsdk pattern)") | ||
flag.Parse() | ||
|
||
var data []byte | ||
var err error | ||
start := time.Now() | ||
fmt.Printf("StartTime: %v\r\n", start) | ||
var totalIterTime time.Duration | ||
var totalEncodeTime time.Duration | ||
var totalChecksumTime time.Duration | ||
var totalDecodeTime time.Duration | ||
var avgIterTime int64 | ||
var avgEncodeTime int64 | ||
var avgChecksumTime int64 | ||
var avgDecodeTime int64 | ||
for i := int64(0); i < iterations; i++ { | ||
startIter := time.Now() | ||
if useBinary { | ||
// we are doing much more than just encode, but | ||
startEncode := time.Now() | ||
data, err = events.NewBinaryEvent(coredataCBOR, smallPayload) | ||
deltaEncode := time.Since(startEncode) | ||
totalEncodeTime += deltaEncode | ||
avgEncodeTime = totalEncodeTime.Nanoseconds() / (i + 1) | ||
fmt.Printf("\r\nCBOR Encode Time: %v\r\n", deltaEncode) | ||
fmt.Printf("\r\nCBOR Avg Encode Time: %v\r\n", time.Duration(avgEncodeTime)) | ||
} else { | ||
data, err = events.NewBasicEvent() | ||
} | ||
if err != nil { | ||
fmt.Sprintln(err.Error()) | ||
return | ||
} | ||
// Calculate a checksum across encoded event data model | ||
startChecksum := time.Now() | ||
checksum := CalcChecksum(data) | ||
deltaChecksum := time.Since(startChecksum) | ||
totalChecksumTime += deltaChecksum | ||
avgChecksumTime = totalChecksumTime.Nanoseconds() / (i + 1) | ||
fmt.Printf("\r\nChecksum Time: %v\r\n", deltaChecksum) | ||
fmt.Printf("\r\nChecksum Avg Time: %v\r\n", time.Duration(avgChecksumTime)) | ||
|
||
// Print actuals if desired | ||
// This will substantially increase overall iteration timing. | ||
if print { | ||
fmt.Printf("Checksum: %x\r\n", checksum) | ||
fmt.Printf("Current time: %v\r\n", events.MakeTimestamp()) | ||
fmt.Printf("Encoded data: \r\n") | ||
os.Stdout.Write(data) | ||
fmt.Printf("\r\n") | ||
} | ||
// decode data, read the event data model, add uuid and encode again.. | ||
//evt := models.Event{} | ||
startDecode := time.Now() | ||
evt, err := decodeEvent(data) | ||
deltaDecode := time.Since(startDecode) | ||
totalDecodeTime += deltaDecode | ||
avgDecodeTime = totalDecodeTime.Nanoseconds() / (i + 1) | ||
fmt.Printf("\r\nCBOR Decode Time: %v\r\n", deltaDecode) | ||
fmt.Printf("\r\nCBOR Avg Decode Time: %v\r\n", time.Duration(avgDecodeTime)) | ||
|
||
if err != nil { | ||
fmt.Printf("\r\nERROR Decoding: %v\r\n", err.Error()) | ||
} | ||
if print { | ||
fmt.Printf("\r\nDecoded data: %v\r\n", evt.String()) | ||
//os.Stdout.Write(evt) | ||
} | ||
deltaIter := time.Since(startIter) | ||
totalIterTime += deltaIter | ||
avgIterTime = totalIterTime.Nanoseconds() / (i + 1) | ||
fmt.Printf("\r\nIteration Time: %v\r\n", deltaIter) | ||
fmt.Printf("Average Iteration (encode+decode+checksum): %v\r\n", time.Duration(avgIterTime)) | ||
} | ||
fmt.Printf("EndTime: %v\r\n", time.Now()) | ||
fmt.Printf("\r\nTOTAL Time taken for %v iterations: %v\r\n", iterations, time.Since(start)) | ||
} | ||
|
||
func CalcChecksum(data []byte) [32]byte { | ||
defer SampleTime(time.Now(), "CalcChecksum") | ||
return sha256.Sum256(data) | ||
} | ||
|
||
func decodeEvent(encodedData []byte) (models.Event, error) { | ||
var err error | ||
useBufferedReader := true | ||
evt := models.Event{} | ||
if (useBufferedReader) { | ||
err = decodeBinaryValueBufferedReader(bytes.NewReader(encodedData), &evt) | ||
} else { | ||
err = decodeBinaryValue(encodedData, &evt) | ||
} | ||
return evt, err | ||
} | ||
|
||
// Directly perform efficient zero copy decode from byte slice | ||
func decodeBinaryValue(encodedData []byte,/* reader io.Reader,*/ value interface{}) error { | ||
var h codec.Handle = new(codec.CborHandle) | ||
var dec *codec.Decoder = codec.NewDecoderBytes(encodedData, h) | ||
var err error = dec.Decode(value) | ||
return err | ||
} | ||
|
||
// Provide a buffered reader for go-codec performance | ||
func decodeBinaryValueBufferedReader(reader io.Reader, value interface{}) error { | ||
var bufReader = bufio.NewReader(reader) | ||
var h codec.Handle = new(codec.CborHandle) | ||
var dec *codec.Decoder = codec.NewDecoder(bufReader, h) | ||
var err error = dec.Decode(value) | ||
return err | ||
} | ||
|
||
func SampleTime(t time.Time, name string) { | ||
elapsed := time.Since(t) | ||
log.Printf("SampleTime: [%s] took %s\n", name, elapsed) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package events | ||
|
||
import ( | ||
"encoding/json" | ||
"github.com/edgexfoundry/go-mod-core-contracts/models" | ||
) | ||
|
||
func NewBasicEvent() (data []byte, err error) { | ||
timestamp := MakeTimestamp() | ||
deviceName := "RandomDevice-1" | ||
evt := models.Event{ Created:timestamp, Modified:timestamp, Device:deviceName } | ||
readings := []models.Reading{} | ||
readings = append(readings, models.Reading{Created:timestamp, Modified:timestamp, Device:deviceName, Name:"Reading1", Value:"ABC"}) | ||
readings = append(readings, models.Reading{Created:timestamp, Modified:timestamp, Device:deviceName, Name:"Reading2", Value:"123"}) | ||
evt.Readings = readings | ||
data, err = json.Marshal(evt) | ||
if err != nil { | ||
return | ||
} | ||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package events | ||
|
||
import ( | ||
"bufio" | ||
"bytes" | ||
"io" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/edgexfoundry/go-mod-core-contracts/models" | ||
"github.com/ugorji/go/codec" | ||
) | ||
|
||
func NewBinaryEvent(coredataCBOR bool, smallPayload bool) (data []byte, err error) { | ||
imgPath, err := findPath() | ||
if err != nil { | ||
return | ||
} | ||
if smallPayload { // 100k | ||
imgPath += "/lebowski.jpg" | ||
} else { //900k (medium) | ||
imgPath += "/1080p_Istanbul_by_yusuf_fersat_5.JPG" | ||
} | ||
|
||
file, err := os.Open(imgPath) | ||
if err != nil { | ||
return | ||
} | ||
defer file.Close() | ||
|
||
fileInfo, _ := file.Stat() | ||
bytes := make([]byte, fileInfo.Size()) | ||
|
||
// read file into bytes | ||
buffer := bufio.NewReader(file) | ||
_, err = buffer.Read(bytes) | ||
|
||
timestamp := MakeTimestamp() | ||
deviceName := "RandomDevice-2" | ||
evt := models.Event{ Created:timestamp, Modified:timestamp, Device:deviceName } | ||
readings := []models.Reading{} | ||
readings = append(readings, models.Reading{Created:timestamp, Modified:timestamp, Device:deviceName, Name:"Reading2", Value:"789"}) | ||
readings = append(readings, models.Reading{Created:timestamp, Modified:timestamp, Device:deviceName, Name:"Reading1", Value:"XYZ"}) | ||
readings = append(readings, models.Reading{Created:timestamp, Modified:timestamp, Device:deviceName, Name:"Reading1", BinaryValue:bytes}) | ||
evt.Readings = readings | ||
|
||
/* Simple form */ | ||
if coredataCBOR { | ||
var handle codec.CborHandle | ||
data = make([]byte, 0, 64) | ||
enc := codec.NewEncoderBytes(&data, &handle) | ||
err = enc.Encode(evt) | ||
} else { | ||
data, _ = encodeBinaryValue(evt) | ||
} | ||
return | ||
} | ||
|
||
func findPath() (path string, err error) { | ||
exec, err := os.Executable() | ||
if err != nil { | ||
return | ||
} | ||
path = filepath.Dir(exec) | ||
path += "/img" | ||
return | ||
} | ||
|
||
func encodeBinaryValue(value interface{}) (encodedData []byte, err error) { | ||
buf := new(bytes.Buffer) | ||
hCbor := new(codec.CborHandle) | ||
enc := codec.NewEncoder(buf, hCbor) | ||
err = enc.Encode(value) | ||
if err == nil { | ||
encodedData = buf.Bytes() | ||
} | ||
return encodedData, err | ||
} | ||
|
||
func decodeBinaryValue(reader io.Reader, value interface{}) error { | ||
// Provide a buffered reader for go-codec performance | ||
var bufReader = bufio.NewReader(reader) | ||
var h codec.Handle = new(codec.CborHandle) | ||
var dec *codec.Decoder = codec.NewDecoder(bufReader, h) | ||
var err error = dec.Decode(value) | ||
return err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package events | ||
|
||
import "time" | ||
|
||
func MakeTimestamp() int64 { | ||
return time.Now().UnixNano() / int64(time.Millisecond) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
module github.com/tobiasmo1/event-bench | ||
|
||
require ( | ||
github.com/edgexfoundry/go-mod-core-contracts v0.0.0-20190418185811-6fa3b1fed53b | ||
github.com/ugorji/go v1.1.4 | ||
) | ||
|
||
replace github.com/edgexfoundry/go-mod-core-contracts => /home/tobiasmo/dev/edgexfoundry/go-mod-core-contracts-tobiasmo1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/edgexfoundry/go-mod-core-contracts v0.0.0-20190418185811-6fa3b1fed53b h1:+AHu/KXjRvTqsFppY2Iue7Bd2qaxf/TXMH6ydptPQpA= | ||
github.com/edgexfoundry/go-mod-core-contracts v0.0.0-20190418185811-6fa3b1fed53b/go.mod h1:yVAVTeH1lbp+3YG2V7sq3iIerZj94lC0rZX1sryGfTY= | ||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= | ||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= | ||
github.com/google/uuid v1.1.0 h1:Jf4mxPC/ziBnoPIdpQdPJ9OeiomAUHLvxmPRSPH9m4s= | ||
github.com/google/uuid v1.1.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | ||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | ||
github.com/ugorji/go v1.1.2 h1:JON3E2/GPW2iDNGoSAusl1KDf5TRQ8k8q7Tp097pZGs= | ||
github.com/ugorji/go v1.1.2/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= | ||
github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw= | ||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= | ||
github.com/ugorji/go/codec v0.0.0-20190316192920-e2bddce071ad h1:Zu1a3eNI3eJefas3yuL6HAKy6eMhRCQFdtZQLC21l6U= | ||
github.com/ugorji/go/codec v0.0.0-20190316192920-e2bddce071ad/go.mod h1:iT03XoTwV7xq/+UGwKO3UbC1nNNlopQiY61beSdrtOA= |