github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/bench/parseint/bench_test.go (about)

     1  package parseint_test
     2  
     3  import (
     4  	"reflect"
     5  	"strconv"
     6  	"testing"
     7  	"unsafe"
     8  )
     9  
    10  func BenchmarkStdAtoi(b *testing.B) {
    11  	var out int
    12  	for i := 0; i < b.N; i++ {
    13  		out, _ = strconv.Atoi("14")
    14  		out, _ = strconv.Atoi("148487491")
    15  	}
    16  	_ = out
    17  }
    18  
    19  func BenchmarkStdAtoiBool(b *testing.B) {
    20  	var out int
    21  	for i := 0; i < b.N; i++ {
    22  		out, _ = parseAtoiBool("14")
    23  		out, _ = parseAtoiBool("148487491")
    24  	}
    25  	_ = out
    26  }
    27  
    28  func BenchmarkStdAtoiNeg(b *testing.B) {
    29  	var out int
    30  	for i := 0; i < b.N; i++ {
    31  		out = parseAtoiNeg("14")
    32  		out = parseAtoiNeg("148487491")
    33  	}
    34  	_ = out
    35  }
    36  
    37  func BenchmarkTailPtr(b *testing.B) {
    38  	var out int
    39  	for i := 0; i < b.N; i++ {
    40  		_ = parseTailPtr("14", &out)
    41  		_ = parseTailPtr("148487491", &out)
    42  	}
    43  	_ = out
    44  }
    45  
    46  func BenchmarkTail(b *testing.B) {
    47  	var out int
    48  	for i := 0; i < b.N; i++ {
    49  		out, _ = parseTail("14")
    50  		out, _ = parseTail("148487491")
    51  	}
    52  	_ = out
    53  }
    54  
    55  func BenchmarkTailNeg(b *testing.B) {
    56  	var out int
    57  	for i := 0; i < b.N; i++ {
    58  		out = parseTailNeg("14")
    59  		out = parseTailNeg("148487491")
    60  	}
    61  	_ = out
    62  }
    63  
    64  func BenchmarkJeff1(b *testing.B) {
    65  	var out int
    66  	for i := 0; i < b.N; i++ {
    67  		out = parseJeff1("14")
    68  		out = parseJeff1("148487491")
    69  	}
    70  	_ = out
    71  }
    72  
    73  func BenchmarkUnsafe(b *testing.B) {
    74  	var out int
    75  	for i := 0; i < b.N; i++ {
    76  		out = parseUnsafe("14")
    77  		out = parseUnsafe("148487491")
    78  	}
    79  	_ = out
    80  }
    81  
    82  func parseAtoiBool(s string) (int, bool) {
    83  	if len(s) == 0 || len(s) > len("999999999") {
    84  		return 0, false
    85  	}
    86  	n := 0
    87  	for _, c := range []byte(s) {
    88  		if c < '0' || c > '9' {
    89  			return 0, false
    90  		}
    91  		n = n*10 + int(c-'0')
    92  	}
    93  	return n, true
    94  }
    95  
    96  func parseAtoiNeg(s string) int {
    97  	if len(s) == 0 || len(s) > len("999999999") {
    98  		return -1
    99  	}
   100  	n := 0
   101  	for _, c := range []byte(s) {
   102  		if c < '0' || c > '9' {
   103  			return -1
   104  		}
   105  		n = n*10 + int(c-'0')
   106  	}
   107  	return n
   108  }
   109  
   110  func parseTailPtr(s string, dst *int) bool {
   111  	if len(s) == 0 || len(s) > len("999999999") {
   112  		*dst = 0
   113  		return false
   114  	}
   115  	n := 0
   116  	for i := 0; i < len(s); i++ {
   117  		d := s[i] - '0'
   118  		if d > 9 {
   119  			*dst = 0
   120  			return false
   121  		}
   122  		n = n*10 + int(d)
   123  	}
   124  	*dst = n
   125  	return true
   126  }
   127  
   128  func parseTail(s string) (int, bool) {
   129  	if len(s) == 0 || len(s) > len("999999999") {
   130  		return 0, false
   131  	}
   132  	n := 0
   133  	for i := 0; i < len(s); i++ {
   134  		d := s[i] - '0'
   135  		if d > 9 {
   136  			return 0, false
   137  		}
   138  		n = n*10 + int(d)
   139  	}
   140  	return n, true
   141  }
   142  
   143  func parseTailNeg(s string) int {
   144  	if len(s) == 0 || len(s) > len("999999999") {
   145  		return -1
   146  	}
   147  	n := 0
   148  	for i := 0; i < len(s); i++ {
   149  		d := s[i] - '0'
   150  		if d > 9 {
   151  			return -1
   152  		}
   153  		n = n*10 + int(d)
   154  	}
   155  	return n
   156  }
   157  
   158  var deltasJeff1 [10]int
   159  
   160  func init() {
   161  	v := 0
   162  	for i := range deltasJeff1 {
   163  		deltasJeff1[i] = v
   164  		v = v*10 + '0'
   165  	}
   166  
   167  	// we do this so that we return -1 when len(s) == 0
   168  	// skips having to check for the len(s) == 0 condition
   169  	deltasJeff1[0] = 1
   170  }
   171  
   172  func parseJeff1(s string) (n int) {
   173  	var c byte
   174  	var i int
   175  
   176  next:
   177  	if i < len(s) {
   178  		c = s[i]
   179  		i = i + 1
   180  		n = 10*n + int(c)
   181  
   182  		if c-'0' > 9 {
   183  			return -1
   184  		}
   185  		goto next
   186  	}
   187  
   188  	if len(s) < len(deltas) {
   189  		return n - deltas[len(s)]
   190  	}
   191  	return -1
   192  }
   193  
   194  var deltas [10]int
   195  
   196  func init() {
   197  	v := 0
   198  	for i := range deltas {
   199  		deltas[i] = v
   200  		v = v*10 + '0'
   201  	}
   202  	deltas[0] = 1
   203  }
   204  
   205  // because life without unsafe and reflect would be too safe.
   206  func parseUnsafe(s string) (n int) {
   207  	sp := unsafe.Pointer((*reflect.StringHeader)(unsafe.Pointer(&s)).Data)
   208  	lp := uintptr(sp) + uintptr(len(s))
   209  next:
   210  	if uintptr(sp) < lp {
   211  		c := *(*byte)(sp)
   212  		n = 10*n + int(c)
   213  		if c-'0' > 9 {
   214  			return -1
   215  		}
   216  		sp = unsafe.Pointer(uintptr(sp) + 1)
   217  		goto next
   218  	}
   219  	if len(s) < len(deltas) {
   220  		return n - deltas[len(s)]
   221  	}
   222  	return -1
   223  }