Initial project import
This commit is contained in:
commit
23f2d29e32
11957 files changed
+1754577
No files matched your search
@@ -0,0 +1,36 @@
|
||||
Benchmark of `x.encoding.asn1` module
|
||||
--------------------------
|
||||
|
||||
This is a benchmark of `x.encoding.asn1` module compared with go version (on free gitpod workspace)
|
||||
|
||||
Regular benchmark produces this result:
|
||||
```bash
|
||||
(dev) $ v run bench/bench.v
|
||||
Benchmarking ASN.1 encode...
|
||||
Average example encode time: 13 µs
|
||||
Benchmarking ASN.1 decode (with asn.decode)...
|
||||
Average (asn1.decode) decode time: 3 µs
|
||||
Benchmarking ASN.1 decode with Example.decode)...
|
||||
Average (Example.decode) decode time: 2 µs
|
||||
```
|
||||
|
||||
Build with `-prod` flag and rerun the bench
|
||||
```bash
|
||||
$ v -prod benchk/bench.v
|
||||
gitpod /workspace/asn1 (dev) $ ./bench/bench
|
||||
Benchmarking ASN.1 encode...
|
||||
Average example encode time: 3 µs
|
||||
Benchmarking ASN.1 decode (with asn.decode)...
|
||||
Average (asn1.decode) decode time: 1 µs
|
||||
Benchmarking ASN.1 decode with Example.decode)...
|
||||
Average (Example.decode) decode time: 1 µs
|
||||
```
|
||||
|
||||
The go version produces following result:
|
||||
```bash
|
||||
$ go run bench/bench.go
|
||||
Benchmarking golang Marshal...
|
||||
Average Marshal time: 1 µs
|
||||
Benchmarking Unmarshal...
|
||||
Average Unmarshal time: 0 µs
|
||||
```
|
||||
@@ -0,0 +1,53 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/asn1"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Example struct {
|
||||
Greeting string `asn1:"utf8"`
|
||||
Answer int
|
||||
Tipe asn1.ObjectIdentifier `asn1:"explicit,tag:1"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
iterations := 1000
|
||||
expected_output := []byte{0x30, 18, 12, 5, 72, 101, 108, 108, 111, 2, 1, 42, 0xA1,
|
||||
6, 6, 4, 43, 6, 1, 3}
|
||||
|
||||
oid := []int{1, 3, 6, 1, 3}
|
||||
|
||||
ex := Example{
|
||||
Greeting: "Hello",
|
||||
Answer: 42,
|
||||
Tipe: asn1.ObjectIdentifier(oid),
|
||||
}
|
||||
fmt.Println("Benchmarking golang Marshal...")
|
||||
var totalMarshalTime int64
|
||||
for i := 0; i < iterations; i++ {
|
||||
start := time.Now()
|
||||
_, err := asn1.Marshal(ex)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
totalMarshalTime += time.Since(start).Microseconds()
|
||||
}
|
||||
avgMarshalTime := totalMarshalTime / int64(iterations)
|
||||
fmt.Printf("Average Marshal time: %d µs\n", avgMarshalTime)
|
||||
|
||||
fmt.Println("Benchmarking Unmarshal...")
|
||||
var totalUnmarshalTime int64
|
||||
var xx Example
|
||||
for i := 0; i < iterations; i++ {
|
||||
start := time.Now()
|
||||
_, err := asn1.Unmarshal(expected_output, &xx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
totalUnmarshalTime += time.Since(start).Microseconds()
|
||||
}
|
||||
avgUnmarshalTime := totalUnmarshalTime / int64(iterations)
|
||||
fmt.Printf("Average Unmarshal time: %d µs\n", avgUnmarshalTime)
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
import time
|
||||
import x.encoding.asn1
|
||||
|
||||
// This Benchmark was performs serialization and deserialization from ASN.1 schema defined as:
|
||||
// ```asn.1
|
||||
// Example ::= SEQUENCE {
|
||||
// greeting UTF8String,
|
||||
// answer INTEGER,
|
||||
// type [1] EXPLICIT OBJECT IDENTIFIER
|
||||
// }
|
||||
// ```
|
||||
struct Example {
|
||||
greeting asn1.Utf8String
|
||||
answer asn1.Integer
|
||||
// you can tag your struct fields with supported options.
|
||||
tipe asn1.ObjectIdentifier @[context_specific: 1; explicit; inner: 6]
|
||||
}
|
||||
|
||||
fn (ex Example) tag() asn1.Tag {
|
||||
return asn1.default_sequence_tag
|
||||
}
|
||||
|
||||
// you can build your payload manually or use `asn1.make_payload`, but be aware,
|
||||
// if your structure contains generics, its may not work (currently).
|
||||
// Updates: Thank to @felipensp. He has a great job to resolve this issue.
|
||||
// Its was resolved in [22724](https://github.com/vlang/v/pull/22724)
|
||||
fn (ex Example) payload() ![]u8 {
|
||||
kd := asn1.KeyDefault(map[string]asn1.Element{})
|
||||
payload := asn1.make_payload[Example](ex, kd)!
|
||||
|
||||
return payload
|
||||
}
|
||||
|
||||
// You can write custom decode routines for the Example structure. This is only one
|
||||
// example, but its possible to do this in other ways with help from this module such
|
||||
// as using the `Parser` codec.
|
||||
fn Example.decode(bytes []u8) !Example {
|
||||
// just call raw .decode on bytes
|
||||
// for example, its should produce sequence type.
|
||||
elem := asn1.decode(bytes)!
|
||||
assert elem.tag().equal(asn1.default_sequence_tag) // should true
|
||||
|
||||
// cast produced element into Sequence type and get the fields.
|
||||
seq := elem.into_object[asn1.Sequence]()!
|
||||
fields := seq.fields()
|
||||
|
||||
// and then, turn every field into desired objects based on your schema.
|
||||
// first two field is not wrapped element, so just turn into real object.
|
||||
greeting := fields[0].into_object[asn1.Utf8String]()!
|
||||
answer := fields[1].into_object[asn1.Integer]()!
|
||||
|
||||
// the third field is a context_specific wrapped element, just unwrap it with the
|
||||
// same options used to encode.
|
||||
oid_tipe := fields[2].unwrap_with_options('context_specific:1;explicit; inner:6')!
|
||||
tipe := oid_tipe.into_object[asn1.ObjectIdentifier]()!
|
||||
|
||||
// then build your Example struct
|
||||
ex := Example{
|
||||
greeting: greeting
|
||||
answer: answer
|
||||
tipe: tipe
|
||||
}
|
||||
return ex
|
||||
}
|
||||
|
||||
fn main() {
|
||||
expected_output := [u8(0x30), 18, u8(12), 5, 72, 101, 108, 108, 111, u8(2), 1, 42, u8(0xA1),
|
||||
6, 6, 4, 43, 6, 1, 3]
|
||||
ex := Example{
|
||||
greeting: asn1.Utf8String.new('Hello')!
|
||||
answer: asn1.Integer.from_int(42)
|
||||
tipe: asn1.ObjectIdentifier.from_ints([1, 3, 6, 1, 3])!
|
||||
}
|
||||
iterations := 1000
|
||||
|
||||
println('Benchmarking ASN.1 encode...')
|
||||
mut total_enc_time := i64(0)
|
||||
for _ in 0 .. iterations {
|
||||
sw := time.new_stopwatch()
|
||||
_ := asn1.encode(ex) or { panic(err) }
|
||||
elapsed := sw.elapsed().microseconds()
|
||||
total_enc_time += elapsed
|
||||
}
|
||||
avg_enc_time := total_enc_time / iterations
|
||||
println('Average example encode time: ${avg_enc_time} µs')
|
||||
|
||||
println('Benchmarking ASN.1 decode (with asn1.decode)...')
|
||||
mut total_dec_time := i64(0)
|
||||
for _ in 0 .. iterations {
|
||||
sw := time.new_stopwatch()
|
||||
_ := asn1.decode(expected_output) or { panic(err) }
|
||||
elapsed := sw.elapsed().microseconds()
|
||||
total_dec_time += elapsed
|
||||
}
|
||||
avg_asn1dec_time := total_dec_time / iterations
|
||||
println('Average (asn1.decode) decode time: ${avg_asn1dec_time} µs')
|
||||
|
||||
println('Benchmarking ASN.1 decode with Example.decode)...')
|
||||
mut total_exdec_time := i64(0)
|
||||
for _ in 0 .. iterations {
|
||||
sw := time.new_stopwatch()
|
||||
_ := asn1.decode(expected_output) or { panic(err) }
|
||||
elapsed := sw.elapsed().microseconds()
|
||||
total_exdec_time += elapsed
|
||||
}
|
||||
avg_exdec_time := total_exdec_time / iterations
|
||||
println('Average (Example.decode) decode time: ${avg_exdec_time} µs')
|
||||
}
|
||||
Reference in new issue
Block a user