From ad2e11ed9c14b848f1d9a7d7591d08bca9a0a719 Mon Sep 17 00:00:00 2001 From: polyrabbit Date: Fri, 27 Sep 2019 15:43:58 +0800 Subject: [PATCH 1/4] Reduce memory allocation --- expression/builtin_cast_vec.go | 7 ++++--- types/time.go | 14 +++++++++++--- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/expression/builtin_cast_vec.go b/expression/builtin_cast_vec.go index 32dd7f32f863c..81553a79fed7c 100644 --- a/expression/builtin_cast_vec.go +++ b/expression/builtin_cast_vec.go @@ -192,11 +192,12 @@ func (b *builtinCastTimeAsDecimalSig) vecEvalDecimal(input *chunk.Chunk, result if result.IsNull(i) { continue } - decimalValue, err := types.ProduceDecWithSpecifiedTp(times[i].ToNumber(), b.tp, sc) - if err != nil { + if err := times[i].FillNumber(&decs[i]); err != nil { + return err + } + if _, err := types.ProduceDecWithSpecifiedTp(&decs[i], b.tp, sc); err != nil { return err } - decs[i] = *decimalValue } return nil } diff --git a/types/time.go b/types/time.go index 0a34b4f870584..25bdb409c9fa4 100644 --- a/types/time.go +++ b/types/time.go @@ -292,8 +292,16 @@ const dateFormat = "%Y%m%d" // 2012-12-12T10:10:10 -> 20121212101010 // 2012-12-12T10:10:10.123456 -> 20121212101010.123456 func (t Time) ToNumber() *MyDecimal { + dec := new(MyDecimal) + t.FillNumber(dec) + return dec +} + +// Same as ToNumber(), but reuses input decimal instead of allocating one. +func (t Time) FillNumber(dec *MyDecimal) error { if t.IsZero() { - return &MyDecimal{} + dec.FromInt(0) + return nil } // Fix issue #1046 @@ -308,6 +316,7 @@ func (t Time) ToNumber() *MyDecimal { s, err := t.DateFormat(tfStr) if err != nil { logutil.BgLogger().Error("[fatal] never happen because we've control the format!") + return err } if t.Fsp > 0 { @@ -316,10 +325,9 @@ func (t Time) ToNumber() *MyDecimal { } // We skip checking error here because time formatted string can be parsed certainly. - dec := new(MyDecimal) err = dec.FromString([]byte(s)) terror.Log(errors.Trace(err)) - return dec + return err } // Convert converts t with type tp. From 1c4a5f6295dc6f31dc1508d7eabc7fb60ec97a9b Mon Sep 17 00:00:00 2001 From: polyrabbit Date: Fri, 27 Sep 2019 15:57:50 +0800 Subject: [PATCH 2/4] Suppress impossible errors --- types/time.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/types/time.go b/types/time.go index 25bdb409c9fa4..aed846e9594dd 100644 --- a/types/time.go +++ b/types/time.go @@ -293,7 +293,9 @@ const dateFormat = "%Y%m%d" // 2012-12-12T10:10:10.123456 -> 20121212101010.123456 func (t Time) ToNumber() *MyDecimal { dec := new(MyDecimal) - t.FillNumber(dec) + err := t.FillNumber(dec) + // We skip checking error here because time formatted string can be parsed certainly. + terror.Log(errors.Trace(err)) return dec } @@ -323,11 +325,7 @@ func (t Time) FillNumber(dec *MyDecimal) error { s1 := fmt.Sprintf("%s.%06d", s, t.Time.Microsecond()) s = s1[:len(s)+int(t.Fsp)+1] } - - // We skip checking error here because time formatted string can be parsed certainly. - err = dec.FromString([]byte(s)) - terror.Log(errors.Trace(err)) - return err + return dec.FromString([]byte(s)) } // Convert converts t with type tp. From 508d4ce04551dcea48d1ee13572742bea55714c9 Mon Sep 17 00:00:00 2001 From: polyrabbit Date: Fri, 27 Sep 2019 16:02:28 +0800 Subject: [PATCH 3/4] Update doc according to lint --- types/time.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/types/time.go b/types/time.go index aed846e9594dd..6aff4804b3e32 100644 --- a/types/time.go +++ b/types/time.go @@ -299,7 +299,8 @@ func (t Time) ToNumber() *MyDecimal { return dec } -// Same as ToNumber(), but reuses input decimal instead of allocating one. +// FillNumber is the same as ToNumber, +// but reuses input decimal instead of allocating one. func (t Time) FillNumber(dec *MyDecimal) error { if t.IsZero() { dec.FromInt(0) From 001f2c34c57bf5e6a366e545ef85163e42d94bc7 Mon Sep 17 00:00:00 2001 From: polyrabbit Date: Fri, 27 Sep 2019 16:50:03 +0800 Subject: [PATCH 4/4] Swallow impossible errors --- expression/builtin_cast_vec.go | 4 +--- types/time.go | 13 ++++++------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/expression/builtin_cast_vec.go b/expression/builtin_cast_vec.go index 81553a79fed7c..94ddc97007549 100644 --- a/expression/builtin_cast_vec.go +++ b/expression/builtin_cast_vec.go @@ -192,9 +192,7 @@ func (b *builtinCastTimeAsDecimalSig) vecEvalDecimal(input *chunk.Chunk, result if result.IsNull(i) { continue } - if err := times[i].FillNumber(&decs[i]); err != nil { - return err - } + times[i].FillNumber(&decs[i]) if _, err := types.ProduceDecWithSpecifiedTp(&decs[i], b.tp, sc); err != nil { return err } diff --git a/types/time.go b/types/time.go index 6aff4804b3e32..746e0507fb460 100644 --- a/types/time.go +++ b/types/time.go @@ -293,18 +293,16 @@ const dateFormat = "%Y%m%d" // 2012-12-12T10:10:10.123456 -> 20121212101010.123456 func (t Time) ToNumber() *MyDecimal { dec := new(MyDecimal) - err := t.FillNumber(dec) - // We skip checking error here because time formatted string can be parsed certainly. - terror.Log(errors.Trace(err)) + t.FillNumber(dec) return dec } // FillNumber is the same as ToNumber, // but reuses input decimal instead of allocating one. -func (t Time) FillNumber(dec *MyDecimal) error { +func (t Time) FillNumber(dec *MyDecimal) { if t.IsZero() { dec.FromInt(0) - return nil + return } // Fix issue #1046 @@ -319,14 +317,15 @@ func (t Time) FillNumber(dec *MyDecimal) error { s, err := t.DateFormat(tfStr) if err != nil { logutil.BgLogger().Error("[fatal] never happen because we've control the format!") - return err } if t.Fsp > 0 { s1 := fmt.Sprintf("%s.%06d", s, t.Time.Microsecond()) s = s1[:len(s)+int(t.Fsp)+1] } - return dec.FromString([]byte(s)) + // We skip checking error here because time formatted string can be parsed certainly. + err = dec.FromString([]byte(s)) + terror.Log(errors.Trace(err)) } // Convert converts t with type tp.