From d7e78e63713ecadd252868e882c34f62adf4fa04 Mon Sep 17 00:00:00 2001 From: dtookey Date: Thu, 1 Aug 2024 07:19:58 -0400 Subject: [PATCH] better float parsing --- 1brc.go | 58 ++++++++++++++++++++++++++++++------------------------- benchmark | 52 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 26 deletions(-) create mode 100644 benchmark diff --git a/1brc.go b/1brc.go index e3bdc46..35542f8 100644 --- a/1brc.go +++ b/1brc.go @@ -19,7 +19,7 @@ const testFile = "dummy.txt" const resultFile = "my_results.txt" const benchFile = "results.txt" -const profile = false +const profile = true var nGoRoutine = 64 @@ -192,35 +192,41 @@ func workerComputePartition(aData []byte, wPart partitionRange, workerNumber int } func fParseFloat(str []byte) float64 { - //kick everything off by computing the remainder - v := float64(fCharToInt(str[len(str)-1])) / 10.0 - positive := true - end := 0 - - if str[0] == '-' { - positive = false - end = 1 - } - - start := len(str) - 3 - oom := 0.0 - for i := start; i >= end; i-- { - v += float64(fCharToInt(str[i])) * math.Pow(10.0, oom) - oom += 1.0 - } - - if positive { - return v - } else { - return -v + switch len(str) { + case 3: + //x.x + a := float64(fCharToInt(str[0])) + b := float64(fCharToInt(str[2])) * 0.1 + return a + b + case 4: + //either xx.x or -x.x + if str[0] == '-' { + //-x.x + a := float64(fCharToInt(str[1])) + b := float64(fCharToInt(str[3])) * 0.1 + return -(a + b) + } else { + //xx.x + a := float64(f2CharToInt(str[0], str[1])) + b := float64(fCharToInt(str[3])) * 0.1 + return a + b + } + case 5: + //-xx.x + a := float64(f2CharToInt(str[1], str[2])) + b := float64(fCharToInt(str[4])) * 0.1 + return -(a + b) + default: + panic(fmt.Errorf("bad float string: %s", string(str))) } } func fCharToInt(b byte) int { - if b >= '0' && b <= '9' { - return int(b - '0') - } - panic(fmt.Errorf("couldn't parse: %v", string(b))) + return int(b - '0') +} + +func f2CharToInt(b1 byte, b2 byte) int { + return int(((b1 - '0') * 10) + (b2 - '0')) } func seekNextNewLine(b []byte, part partitionRange, last int64) int64 { diff --git a/benchmark b/benchmark new file mode 100644 index 0000000..a54687b --- /dev/null +++ b/benchmark @@ -0,0 +1,52 @@ +Showing nodes accounting for 84.49s, 99.24% of 85.14s total +Dropped 35 nodes (cum <= 0.43s) + flat flat% sum% cum cum% + 29.91s 35.13% 35.13% 80.51s 94.56% main.workerComputePartition + 14.55s 17.09% 52.22% 20.92s 24.57% runtime.mapaccess2_fast64 + 7.65s 8.99% 61.21% 9.47s 11.12% runtime.mapassign_fast64 + 7.50s 8.81% 70.01% 7.50s 8.81% hash/fnv.(*sum64).Write (inline) + 6.55s 7.69% 77.71% 6.55s 7.69% main.seekNextNewLine (inline) + 4.58s 5.38% 83.09% 4.58s 5.38% runtime.memhash64 + 4.48s 5.26% 88.35% 4.48s 5.26% runtime.cgocall + 3.61s 4.24% 92.59% 6.16s 7.24% main.fParseFloat + 2.76s 3.24% 95.83% 2.76s 3.24% runtime.add (inline) + 2.55s 3.00% 98.83% 2.55s 3.00% main.fCharToInt (inline) + 0.35s 0.41% 99.24% 0.66s 0.78% runtime.bucketMask (inline) + 0 0% 99.24% 4.48s 5.26% internal/poll.(*FD).Read + 0 0% 99.24% 4.48s 5.26% main.main + 0 0% 99.24% 4.48s 5.26% main.oneBRC + 0 0% 99.24% 4.48s 5.26% os.(*File).Read + 0 0% 99.24% 4.48s 5.26% os.(*File).read (inline) + 0 0% 99.24% 4.48s 5.26% os.ReadFile + 0 0% 99.24% 4.48s 5.26% runtime.main + 0 0% 99.24% 4.48s 5.26% syscall.Read + 0 0% 99.24% 4.48s 5.26% syscall.ReadFile (inline) + 0 0% 99.24% 4.48s 5.26% syscall.Syscall6 + 0 0% 99.24% 4.48s 5.26% syscall.SyscallN + 0 0% 99.24% 4.48s 5.26% syscall.readFile + + + flat flat% sum% cum cum% + 29.18s 34.19% 34.19% 80.72s 94.58% main.workerComputePartition + 14.53s 17.02% 51.21% 21.08s 24.70% runtime.mapaccess2_fast64 + 8.30s 9.72% 60.94% 10.42s 12.21% runtime.mapassign_fast64 + 7.39s 8.66% 69.60% 7.39s 8.66% hash/fnv.(*sum64).Write (inline) + 6.36s 7.45% 77.05% 6.36s 7.45% main.seekNextNewLine (inline) + 4.73s 5.54% 82.59% 4.73s 5.54% runtime.memhash64 + 4.48s 5.25% 87.84% 4.48s 5.25% runtime.cgocall + 3.76s 4.41% 92.24% 6.28s 7.36% main.fParseFloat + 3s 3.51% 95.76% 3s 3.51% runtime.add (inline) + 2.52s 2.95% 98.71% 2.52s 2.95% main.fCharToInt (inline) + 0.34s 0.4% 99.11% 0.68s 0.8% runtime.bucketMask (inline) + 0 0% 99.11% 4.48s 5.25% internal/poll.(*FD).Read + 0 0% 99.11% 4.48s 5.25% main.main + 0 0% 99.11% 4.48s 5.25% main.oneBRC + 0 0% 99.11% 4.48s 5.25% os.(*File).Read + 0 0% 99.11% 4.48s 5.25% os.(*File).read (inline) + 0 0% 99.11% 4.48s 5.25% os.ReadFile + 0 0% 99.11% 4.48s 5.25% runtime.main + 0 0% 99.11% 4.48s 5.25% syscall.Read + 0 0% 99.11% 4.48s 5.25% syscall.ReadFile (inline) + 0 0% 99.11% 4.48s 5.25% syscall.Syscall6 + 0 0% 99.11% 4.48s 5.25% syscall.SyscallN + 0 0% 99.11% 4.48s 5.25% syscall.readFile