Skip to content

Commit

Permalink
Merge pull request #2 from usk81/dev
Browse files Browse the repository at this point in the history
commonalize functions and performance tuning
  • Loading branch information
usk81 committed Jan 2, 2018
2 parents 098b409 + 1d76075 commit 90522b8
Show file tree
Hide file tree
Showing 29 changed files with 2,214 additions and 339 deletions.
86 changes: 80 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,42 +63,116 @@ func main() {

var tb generic.Bool
tb.Set(v)
vb := tb.Value()
vb := tb.Weak()
fmt.Printf("%v, (%T)\n", vb, vb)
// true, (bool)

var tf generic.Float
tf.Set(v)
vf := tf.Value()
vf := tf.Weak()
fmt.Printf("%v, (%T)\n", vf, vf)
// 1, (float64)

var ti generic.Int
ti.Set(v)
vi := ti.Value()
vi := ti.Weak()
fmt.Printf("%v, (%T)\n", vi, vi)
// 1, (int64)

var ts generic.String
ts.Set(v)
vs := ts.Value()
vs := ts.Weak()
fmt.Printf("%v, (%T)\n", vs, vs)
// 1, (string)

var tt generic.Time
tt.Set(v)
vt := tt.Value()
vt := tt.Weak()
fmt.Printf("%v, (%T)\n", vt.UTC(), vt)
// 1970-01-01 09:00:01 +0900 JST, (time.Time)

var tu generic.Uint
tu.Set(v)
vu := tu.Value()
vu := tu.Weak()
fmt.Printf("%v, (%T)\n", vu, vu)
// 1, (uint64)
}
```

## Benchmarks

### Marshal

#### Bool

| version | requests | /op | B/op | allocs/op |
|---|---|---|---|---|
| 1.0.0 | 5000000 | 240 ns | 185 | 3 |
| 2.0.0 | 200000000 | 6.69 ns | 0 | 0 |

#### Float

| version | requests | /op | B/op | allocs/op |
|---|---|---|---|---|
| 1.0.0 | 3000000 | 425 ns | 192 | 3 |
| 2.0.0 | 5000000 | 260 ns | 64 | 3 |

#### Int

| version | requests | /op | B/op | allocs/op |
|---|---|---|---|---|
| 1.0.0 | 5000000 | 265 ns | 192 | 3 |
| 2.0.0 | 20000000 | 70.5 ns | 16 | 2 |

#### String (small)

| version | requests | /op | B/op | allocs/op |
|---|---|---|---|---|
| 1.0.0 | 3000000 | 382 ns | 200 | 3 |
| 2.0.0 | 20000000 | 89.0 ns | 128 | 2 |

#### String (Large)

| version | requests | /op | B/op | allocs/op |
|---|---|---|---|---|
| 1.0.0 | 1000000 | 1056 ns | 776 | 4 |
| 2.0.0 | 5000000 | 237 ns | 896 | 2 |

#### Time

| version | requests | /op | B/op | allocs/op |
|---|---|---|---|---|
| 1.0.0 | 1000000 | 1122 ns | 360 | 5 |
| 2.0.0 | 3000000 | 401 ns | 48 | 1 |

#### TimestampMS

| version | requests | /op | B/op | allocs/op |
|---|---|---|---|---|
| 1.0.0 | 20000000 | 97.9 ns | 32 | 2 |
| 2.0.0 | 20000000 | 91.2 ns | 32 | 2 |

#### TimestampNano

| version | requests | /op | B/op | allocs/op |
|---|---|---|---|---|
| 1.0.0 | 10000000 | 114 ns | 64 | 2 |
| 2.0.0 | 10000000 | 112 ns | 64 | 2 |

#### Timestamp

| version | requests | /op | B/op | allocs/op |
|---|---|---|---|---|
| 1.0.0 | 20000000 | 88.4 ns | 32 | 2 |
| 2.0.0 | 20000000 | 86.7 ns | 32 | 2 |

#### Uint

| version | requests | /op | B/op | allocs/op |
|---|---|---|---|---|
| 1.0.0 | 5000000 | 277 ns | 192 | 3 |
| 2.0.0 | 20000000 | 64.2 ns | 16 | 2 |

## Licence

[MIT](https://github.com/usk81/generic/blob/master/LICENSE)
Expand Down
183 changes: 58 additions & 125 deletions convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func asInt(x interface{}) (result int64, isValid ValidFlag, err error) {
result = int64(x.(float64))
case bool:
b := x.(bool)
if b == true {
if b {
result = 1
} else {
result = 0
Expand Down Expand Up @@ -193,7 +193,7 @@ func asTime(x interface{}) (result time.Time, isValid ValidFlag, err error) {
case time.Time:
result = x.(time.Time)
if result.IsZero() {
return result, false, nil
return result, true, nil
}
default:
return result, false, ErrInvalidGenericValue{Value: x}
Expand All @@ -203,137 +203,23 @@ func asTime(x interface{}) (result time.Time, isValid ValidFlag, err error) {

// asTimestamp converts a specified value to time.Time value.
func asTimestamp(x interface{}) (result time.Time, isValid ValidFlag, err error) {
var i int64
switch x.(type) {
case nil:
return result, false, nil
case time.Time:
result = x.(time.Time)
if result.IsZero() {
return result, false, nil
}
return result, true, nil
case int:
i = int64(x.(int))
case int8:
i = int64(x.(int8))
case int16:
i = int64(x.(int16))
case int32:
i = int64(x.(int32))
case int64:
i = x.(int64)
case uint:
i = int64(x.(uint))
case uint8:
i = int64(x.(uint8))
case uint16:
i = int64(x.(uint16))
case uint32:
i = int64(x.(uint32))
case uint64:
i = int64(x.(uint64))
case float32:
i = int64(x.(float32))
case float64:
i = int64(x.(float64))
default:
return result, false, ErrInvalidGenericValue{Value: x}
}
if i < 0 {
return result, false, ErrInvalidGenericValue{Value: x}
}
return time.Unix(i, 0), true, nil
return asTimestampWithFunc(x, func(i int64) time.Time {
return time.Unix(i, 0)
})
}

// asTimestampNanoseconds converts a specified value to time.Time value.
func asTimestampNanoseconds(x interface{}) (result time.Time, isValid ValidFlag, err error) {
var i int64
switch x.(type) {
case nil:
return result, false, nil
case time.Time:
result = x.(time.Time)
if result.IsZero() {
return result, false, nil
}
return result, true, nil
case int:
i = int64(x.(int))
case int8:
i = int64(x.(int8))
case int16:
i = int64(x.(int16))
case int32:
i = int64(x.(int32))
case int64:
i = x.(int64)
case uint:
i = int64(x.(uint))
case uint8:
i = int64(x.(uint8))
case uint16:
i = int64(x.(uint16))
case uint32:
i = int64(x.(uint32))
case uint64:
i = int64(x.(uint64))
case float32:
i = int64(x.(float32))
case float64:
i = int64(x.(float64))
default:
return result, false, ErrInvalidGenericValue{Value: x}
}
if i < 0 {
return result, false, ErrInvalidGenericValue{Value: x}
}
return time.Unix(0, i), true, nil
return asTimestampWithFunc(x, func(i int64) time.Time {
return time.Unix(0, i)
})
}

// asTimestampMilliseconds converts a specified value to time.Time value.
func asTimestampMilliseconds(x interface{}) (result time.Time, isValid ValidFlag, err error) {
var i int64
switch x.(type) {
case nil:
return result, false, nil
case time.Time:
result = x.(time.Time)
if result.IsZero() {
return result, false, nil
}
return result, true, nil
case int:
i = int64(x.(int))
case int8:
i = int64(x.(int8))
case int16:
i = int64(x.(int16))
case int32:
i = int64(x.(int32))
case int64:
i = x.(int64)
case uint:
i = int64(x.(uint))
case uint8:
i = int64(x.(uint8))
case uint16:
i = int64(x.(uint16))
case uint32:
i = int64(x.(uint32))
case uint64:
i = int64(x.(uint64))
case float32:
i = int64(x.(float32))
case float64:
i = int64(x.(float64))
default:
return result, false, ErrInvalidGenericValue{Value: x}
}
if i < 0 {
return result, false, ErrInvalidGenericValue{Value: x}
}
return time.Unix(0, i*1000000), true, nil
return asTimestampWithFunc(x, func(i int64) time.Time {
return time.Unix(0, i*1000000)
})
}

// asBool converts a specified value to uint64 value.
Expand Down Expand Up @@ -410,3 +296,50 @@ func asUint(x interface{}) (result uint64, isValid ValidFlag, err error) {
}
return result, true, nil
}

func asTimestampWithFunc(x interface{}, f func(i int64) time.Time) (result time.Time, isValid ValidFlag, err error) {
var i int64
switch x.(type) {
case nil:
return result, false, nil
case time.Time:
result = x.(time.Time)
if result.IsZero() {
return result, true, nil
}
return result, true, nil
case string:
result, err = time.Parse(time.RFC3339Nano, x.(string))
return result, err == nil, err
case int:
i = int64(x.(int))
case int8:
i = int64(x.(int8))
case int16:
i = int64(x.(int16))
case int32:
i = int64(x.(int32))
case int64:
i = x.(int64)
case uint:
i = int64(x.(uint))
case uint8:
i = int64(x.(uint8))
case uint16:
i = int64(x.(uint16))
case uint32:
i = int64(x.(uint32))
case uint64:
i = int64(x.(uint64))
case float32:
i = int64(x.(float32))
case float64:
i = int64(x.(float64))
default:
return result, false, ErrInvalidGenericValue{Value: x}
}
if i < 0 {
return result, false, ErrInvalidGenericValue{Value: x}
}
return f(i), true, nil
}
Loading

0 comments on commit 90522b8

Please sign in to comment.