diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-01-13 05:11:45 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-01-13 05:11:45 +0000 |
commit | df4aa89a5e7acb315655f193e7f549e8d32367e2 (patch) | |
tree | eb5eccc07097c5fcf940967f33ab84a7d47c96fe /libgo/go/fmt | |
parent | f83fa0bf8f411697ec908cfa86ee6faf4cd9c476 (diff) | |
download | gcc-df4aa89a5e7acb315655f193e7f549e8d32367e2.zip gcc-df4aa89a5e7acb315655f193e7f549e8d32367e2.tar.gz gcc-df4aa89a5e7acb315655f193e7f549e8d32367e2.tar.bz2 |
libgo: Update to weekly.2011-12-22.
From-SVN: r183150
Diffstat (limited to 'libgo/go/fmt')
-rw-r--r-- | libgo/go/fmt/fmt_test.go | 98 | ||||
-rw-r--r-- | libgo/go/fmt/format.go | 93 | ||||
-rw-r--r-- | libgo/go/fmt/print.go | 8 |
3 files changed, 84 insertions, 115 deletions
diff --git a/libgo/go/fmt/fmt_test.go b/libgo/go/fmt/fmt_test.go index d7fe296..d34a4f8 100644 --- a/libgo/go/fmt/fmt_test.go +++ b/libgo/go/fmt/fmt_test.go @@ -506,78 +506,42 @@ func BenchmarkSprintfFloat(b *testing.B) { } } +var mallocBuf bytes.Buffer + +var mallocTest = []struct { + count int + desc string + fn func() +}{ + {0, `Sprintf("")`, func() { Sprintf("") }}, + {1, `Sprintf("xxx")`, func() { Sprintf("xxx") }}, + {1, `Sprintf("%x")`, func() { Sprintf("%x", 7) }}, + {2, `Sprintf("%s")`, func() { Sprintf("%s", "hello") }}, + {1, `Sprintf("%x %x")`, func() { Sprintf("%x", 7, 112) }}, + {1, `Sprintf("%g")`, func() { Sprintf("%g", 3.14159) }}, + {0, `Fprintf(buf, "%x %x %x")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%x %x %x", 7, 8, 9) }}, + {1, `Fprintf(buf, "%s")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%s", "hello") }}, +} + +var _ bytes.Buffer + func TestCountMallocs(t *testing.T) { if testing.Short() { return } - const N = 100 - runtime.UpdateMemStats() - mallocs := 0 - runtime.MemStats.Mallocs - for i := 0; i < N; i++ { - Sprintf("") - } - runtime.UpdateMemStats() - mallocs += runtime.MemStats.Mallocs - Printf("mallocs per Sprintf(\"\"): %d\n", mallocs/N) - runtime.UpdateMemStats() - mallocs = 0 - runtime.MemStats.Mallocs - for i := 0; i < N; i++ { - Sprintf("xxx") - } - runtime.UpdateMemStats() - mallocs += runtime.MemStats.Mallocs - Printf("mallocs per Sprintf(\"xxx\"): %d\n", mallocs/N) - runtime.UpdateMemStats() - mallocs = 0 - runtime.MemStats.Mallocs - for i := 0; i < N; i++ { - Sprintf("%x", i) - } - runtime.UpdateMemStats() - mallocs += runtime.MemStats.Mallocs - Printf("mallocs per Sprintf(\"%%x\"): %d\n", mallocs/N) - runtime.UpdateMemStats() - mallocs = 0 - runtime.MemStats.Mallocs - for i := 0; i < N; i++ { - Sprintf("%s", "hello") - } - runtime.UpdateMemStats() - mallocs += runtime.MemStats.Mallocs - Printf("mallocs per Sprintf(\"%%s\"): %d\n", mallocs/N) - runtime.UpdateMemStats() - mallocs = 0 - runtime.MemStats.Mallocs - for i := 0; i < N; i++ { - Sprintf("%x %x", i, i) - } - runtime.UpdateMemStats() - mallocs += runtime.MemStats.Mallocs - Printf("mallocs per Sprintf(\"%%x %%x\"): %d\n", mallocs/N) - runtime.UpdateMemStats() - mallocs = 0 - runtime.MemStats.Mallocs - for i := 0; i < N; i++ { - Sprintf("%g", 3.14159) - } - runtime.UpdateMemStats() - mallocs += runtime.MemStats.Mallocs - Printf("mallocs per Sprintf(\"%%g\"): %d\n", mallocs/N) - buf := new(bytes.Buffer) - runtime.UpdateMemStats() - mallocs = 0 - runtime.MemStats.Mallocs - for i := 0; i < N; i++ { - buf.Reset() - Fprintf(buf, "%x %x %x", i, i, i) - } - runtime.UpdateMemStats() - mallocs += runtime.MemStats.Mallocs - Printf("mallocs per Fprintf(buf, \"%%x %%x %%x\"): %d\n", mallocs/N) - runtime.UpdateMemStats() - mallocs = 0 - runtime.MemStats.Mallocs - for i := 0; i < N; i++ { - buf.Reset() - Fprintf(buf, "%s", "hello") + for _, mt := range mallocTest { + const N = 100 + runtime.UpdateMemStats() + mallocs := 0 - runtime.MemStats.Mallocs + for i := 0; i < N; i++ { + mt.fn() + } + runtime.UpdateMemStats() + mallocs += runtime.MemStats.Mallocs + if mallocs/N != uint64(mt.count) { + t.Errorf("%s: expected %d mallocs, got %d", mt.desc, mt.count, mallocs/N) + } } - runtime.UpdateMemStats() - mallocs += runtime.MemStats.Mallocs - Printf("mallocs per Fprintf(buf, \"%%s\"): %d\n", mallocs/N) } type flagPrinter struct{} diff --git a/libgo/go/fmt/format.go b/libgo/go/fmt/format.go index 5f62c06..78d9e99 100644 --- a/libgo/go/fmt/format.go +++ b/libgo/go/fmt/format.go @@ -154,12 +154,17 @@ func putint(buf []byte, base, val uint64, digits string) int { return i - 1 } +var ( + trueBytes = []byte("true") + falseBytes = []byte("false") +) + // fmt_boolean formats a boolean. func (f *fmt) fmt_boolean(v bool) { if v { - f.padString("true") + f.pad(trueBytes) } else { - f.padString("false") + f.pad(falseBytes) } } @@ -283,31 +288,18 @@ func (f *fmt) fmt_s(s string) { } // fmt_sx formats a string as a hexadecimal encoding of its bytes. -func (f *fmt) fmt_sx(s string) { - t := "" +func (f *fmt) fmt_sx(s, digits string) { + // TODO: Avoid buffer by pre-padding. + var b bytes.Buffer for i := 0; i < len(s); i++ { if i > 0 && f.space { - t += " " + b.WriteByte(' ') } v := s[i] - t += string(ldigits[v>>4]) - t += string(ldigits[v&0xF]) + b.WriteByte(digits[v>>4]) + b.WriteByte(digits[v&0xF]) } - f.padString(t) -} - -// fmt_sX formats a string as an uppercase hexadecimal encoding of its bytes. -func (f *fmt) fmt_sX(s string) { - t := "" - for i := 0; i < len(s); i++ { - if i > 0 && f.space { - t += " " - } - v := s[i] - t += string(udigits[v>>4]) - t += string(udigits[v&0xF]) - } - f.padString(t) + f.pad(b.Bytes()) } // fmt_q formats a string as a double-quoted, escaped Go string constant. @@ -329,13 +321,13 @@ func (f *fmt) fmt_q(s string) { // fmt_qc formats the integer as a single-quoted, escaped Go character constant. // If the character is not valid Unicode, it will print '\ufffd'. func (f *fmt) fmt_qc(c int64) { - var quoted string + var quoted []byte if f.plus { - quoted = strconv.QuoteRuneToASCII(rune(c)) + quoted = strconv.AppendQuoteRuneToASCII(f.intbuf[0:0], rune(c)) } else { - quoted = strconv.QuoteRune(rune(c)) + quoted = strconv.AppendQuoteRune(f.intbuf[0:0], rune(c)) } - f.padString(quoted) + f.pad(quoted) } // floating-point @@ -347,57 +339,70 @@ func doPrec(f *fmt, def int) int { return def } -// Add a plus sign or space to the floating-point string representation if missing and required. -func (f *fmt) plusSpace(s string) { - if s[0] != '-' { +// formatFloat formats a float64; it is an efficient equivalent to f.pad(strconv.FormatFloat()...). +func (f *fmt) formatFloat(v float64, verb byte, prec, n int) { + // We leave one byte at the beginning of f.intbuf for a sign if needed, + // and make it a space, which we might be able to use. + f.intbuf[0] = ' ' + slice := strconv.AppendFloat(f.intbuf[0:1], v, verb, prec, n) + // Add a plus sign or space to the floating-point string representation if missing and required. + // The formatted number starts at slice[1]. + switch slice[1] { + case '-', '+': + // We're set; drop the leading space. + slice = slice[1:] + default: + // There's no sign, but we might need one. if f.plus { - s = "+" + s + slice[0] = '+' } else if f.space { - s = " " + s + // space is already there + } else { + slice = slice[1:] } } - f.padString(s) + f.pad(slice) } // fmt_e64 formats a float64 in the form -1.23e+12. -func (f *fmt) fmt_e64(v float64) { f.plusSpace(strconv.FormatFloat(v, 'e', doPrec(f, 6), 64)) } +func (f *fmt) fmt_e64(v float64) { f.formatFloat(v, 'e', doPrec(f, 6), 64) } // fmt_E64 formats a float64 in the form -1.23E+12. -func (f *fmt) fmt_E64(v float64) { f.plusSpace(strconv.FormatFloat(v, 'E', doPrec(f, 6), 64)) } +func (f *fmt) fmt_E64(v float64) { f.formatFloat(v, 'E', doPrec(f, 6), 64) } // fmt_f64 formats a float64 in the form -1.23. -func (f *fmt) fmt_f64(v float64) { f.plusSpace(strconv.FormatFloat(v, 'f', doPrec(f, 6), 64)) } +func (f *fmt) fmt_f64(v float64) { f.formatFloat(v, 'f', doPrec(f, 6), 64) } // fmt_g64 formats a float64 in the 'f' or 'e' form according to size. -func (f *fmt) fmt_g64(v float64) { f.plusSpace(strconv.FormatFloat(v, 'g', doPrec(f, -1), 64)) } +func (f *fmt) fmt_g64(v float64) { f.formatFloat(v, 'g', doPrec(f, -1), 64) } // fmt_g64 formats a float64 in the 'f' or 'E' form according to size. -func (f *fmt) fmt_G64(v float64) { f.plusSpace(strconv.FormatFloat(v, 'G', doPrec(f, -1), 64)) } +func (f *fmt) fmt_G64(v float64) { f.formatFloat(v, 'G', doPrec(f, -1), 64) } // fmt_fb64 formats a float64 in the form -123p3 (exponent is power of 2). -func (f *fmt) fmt_fb64(v float64) { f.plusSpace(strconv.FormatFloat(v, 'b', 0, 64)) } +func (f *fmt) fmt_fb64(v float64) { f.formatFloat(v, 'b', 0, 64) } // float32 // cannot defer to float64 versions // because it will get rounding wrong in corner cases. // fmt_e32 formats a float32 in the form -1.23e+12. -func (f *fmt) fmt_e32(v float32) { f.plusSpace(strconv.FormatFloat(float64(v), 'e', doPrec(f, 6), 32)) } +func (f *fmt) fmt_e32(v float32) { f.formatFloat(float64(v), 'e', doPrec(f, 6), 32) } // fmt_E32 formats a float32 in the form -1.23E+12. -func (f *fmt) fmt_E32(v float32) { f.plusSpace(strconv.FormatFloat(float64(v), 'E', doPrec(f, 6), 32)) } +func (f *fmt) fmt_E32(v float32) { f.formatFloat(float64(v), 'E', doPrec(f, 6), 32) } // fmt_f32 formats a float32 in the form -1.23. -func (f *fmt) fmt_f32(v float32) { f.plusSpace(strconv.FormatFloat(float64(v), 'f', doPrec(f, 6), 32)) } +func (f *fmt) fmt_f32(v float32) { f.formatFloat(float64(v), 'f', doPrec(f, 6), 32) } // fmt_g32 formats a float32 in the 'f' or 'e' form according to size. -func (f *fmt) fmt_g32(v float32) { f.plusSpace(strconv.FormatFloat(float64(v), 'g', doPrec(f, -1), 32)) } +func (f *fmt) fmt_g32(v float32) { f.formatFloat(float64(v), 'g', doPrec(f, -1), 32) } // fmt_G32 formats a float32 in the 'f' or 'E' form according to size. -func (f *fmt) fmt_G32(v float32) { f.plusSpace(strconv.FormatFloat(float64(v), 'G', doPrec(f, -1), 32)) } +func (f *fmt) fmt_G32(v float32) { f.formatFloat(float64(v), 'G', doPrec(f, -1), 32) } // fmt_fb32 formats a float32 in the form -123p3 (exponent is power of 2). -func (f *fmt) fmt_fb32(v float32) { f.padString(strconv.FormatFloat(float64(v), 'b', 0, 32)) } +func (f *fmt) fmt_fb32(v float32) { f.formatFloat(float64(v), 'b', 0, 32) } // fmt_c64 formats a complex64 according to the verb. func (f *fmt) fmt_c64(v complex64, verb rune) { diff --git a/libgo/go/fmt/print.go b/libgo/go/fmt/print.go index 9f157da..3b7d346 100644 --- a/libgo/go/fmt/print.go +++ b/libgo/go/fmt/print.go @@ -503,9 +503,9 @@ func (p *pp) fmtString(v string, verb rune, goSyntax bool) { case 's': p.fmt.fmt_s(v) case 'x': - p.fmt.fmt_sx(v) + p.fmt.fmt_sx(v, ldigits) case 'X': - p.fmt.fmt_sX(v) + p.fmt.fmt_sx(v, udigits) case 'q': p.fmt.fmt_q(v) default: @@ -542,9 +542,9 @@ func (p *pp) fmtBytes(v []byte, verb rune, goSyntax bool, depth int) { case 's': p.fmt.fmt_s(s) case 'x': - p.fmt.fmt_sx(s) + p.fmt.fmt_sx(s, ldigits) case 'X': - p.fmt.fmt_sX(s) + p.fmt.fmt_sx(s, udigits) case 'q': p.fmt.fmt_q(s) default: |