Skip to content

Commit 1cc77e6

Browse files
committed
import itoa_ljust.c for fast number printing
converted from C++. for best speed, needs to be built with O3
1 parent d9dfbe0 commit 1cc77e6

File tree

5 files changed

+219
-1
lines changed

5 files changed

+219
-1
lines changed

LICENSE.itoa_ljust

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
Copyright (c) 2016, Arturo Martin-de-Nicolas
2+
3+
https://github.com/amdn/itoa_ljust/
4+
All rights reserved.
5+
6+
This implementation is loosely based on the structure of FastInt32ToBufferLeft
7+
in:
8+
9+
Protocol Buffers - Google's data interchange format
10+
Copyright 2008 Google Inc. All rights reserved.
11+
https://developers.google.com/protocol-buffers/
12+
13+
Redistribution and use in source and binary forms, with or without
14+
modification, are permitted provided that the following conditions are
15+
met:
16+
17+
* Redistributions of source code must retain the above copyright
18+
notice, this list of conditions and the following disclaimer.
19+
20+
* Redistributions in binary form must reproduce the above
21+
copyright notice, this list of conditions and the following disclaimer
22+
in the documentation and/or other materials provided with the
23+
distribution.
24+
25+
* Neither the name of Google Inc. nor the names of its
26+
contributors may be used to endorse or promote products derived from
27+
this software without specific prior written permission.
28+
29+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Makefile.am

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ memcached_SOURCES = memcached.c memcached.h \
2121
trace.h cache.h sasl_defs.h \
2222
bipbuffer.c bipbuffer.h \
2323
logger.c logger.h \
24-
crawler.c crawler.h
24+
crawler.c crawler.h \
25+
itoa_ljust.c itoa_ljust.h
2526

2627
if BUILD_CACHE
2728
memcached_SOURCES += cache.c

itoa_ljust.c

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
//=== itoa_ljust.cpp - Fast integer to ascii conversion --*- C++ -*-//
2+
//
3+
// Substantially simplified (and slightly faster) version
4+
// based on the following functions in Google's protocol buffers:
5+
//
6+
// FastInt32ToBufferLeft()
7+
// FastUInt32ToBufferLeft()
8+
// FastInt64ToBufferLeft()
9+
// FastUInt64ToBufferLeft()
10+
//
11+
// Differences:
12+
// 1) Greatly simplified
13+
// 2) Avoids GOTO statements - uses "switch" instead and relies on
14+
// compiler constant folding and propagation for high performance
15+
// 3) Avoids unary minus of signed types - undefined behavior if value
16+
// is INT_MIN in platforms using two's complement representation
17+
// 4) Uses memcpy to store 2 digits at a time - lets the compiler
18+
// generate a 2-byte load/store in platforms that support
19+
// unaligned access, this is faster (and less code) than explicitly
20+
// loading and storing each byte
21+
//
22+
// Copyright (c) 2016 Arturo Martin-de-Nicolas
23+
24+
// https://github.com/amdn/itoa_ljust/
25+
//
26+
// Released under the BSD 3-Clause License, see Google's original copyright
27+
// and license below.
28+
//===----------------------------------------------------------------------===//
29+
30+
// Protocol Buffers - Google's data interchange format
31+
// Copyright 2008 Google Inc. All rights reserved.
32+
// https://developers.google.com/protocol-buffers/
33+
//
34+
// Redistribution and use in source and binary forms, with or without
35+
// modification, are permitted provided that the following conditions are
36+
// met:
37+
//
38+
// * Redistributions of source code must retain the above copyright
39+
// notice, this list of conditions and the following disclaimer.
40+
// * Redistributions in binary form must reproduce the above
41+
// copyright notice, this list of conditions and the following disclaimer
42+
// in the documentation and/or other materials provided with the
43+
// distribution.
44+
// * Neither the name of Google Inc. nor the names of its
45+
// contributors may be used to endorse or promote products derived from
46+
// this software without specific prior written permission.
47+
//
48+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
49+
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
50+
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
51+
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
52+
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
53+
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
54+
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
55+
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
56+
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
57+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
58+
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59+
//===----------------------------------------------------------------------===//
60+
61+
#include "itoa_ljust.h"
62+
#include <string.h>
63+
64+
static const char lut[201] =
65+
"0001020304050607080910111213141516171819"
66+
"2021222324252627282930313233343536373839"
67+
"4041424344454647484950515253545556575859"
68+
"6061626364656667686970717273747576777879"
69+
"8081828384858687888990919293949596979899";
70+
71+
#define dd(u) ((const uint16_t)(lut[u]))
72+
73+
static inline char* out2(const int d, char* p) {
74+
memcpy(p, &((uint16_t *)lut)[d], 2);
75+
return p + 2;
76+
}
77+
78+
static inline char* out1(const char in, char* p) {
79+
memcpy(p, &in, 1);
80+
return p + 1;
81+
}
82+
83+
static inline int digits( uint32_t u, unsigned k, int* d, char** p, int n ) {
84+
if (u < k*10) {
85+
*d = u / k;
86+
*p = out1('0'+*d, *p);
87+
--n;
88+
}
89+
return n;
90+
}
91+
92+
static inline char* itoa(uint32_t u, char* p, int d, int n) {
93+
switch(n) {
94+
case 10: d = u / 100000000; p = out2( d, p );
95+
case 9: u -= d * 100000000;
96+
case 8: d = u / 1000000; p = out2( d, p );
97+
case 7: u -= d * 1000000;
98+
case 6: d = u / 10000; p = out2( d, p );
99+
case 5: u -= d * 10000;
100+
case 4: d = u / 100; p = out2( d, p );
101+
case 3: u -= d * 100;
102+
case 2: d = u / 1; p = out2( d, p );
103+
case 1: ;
104+
}
105+
*p = '\0';
106+
return p;
107+
}
108+
109+
char* itoa_u32(uint32_t u, char* p) {
110+
int d,n;
111+
if (u >=100000000) n = digits(u, 100000000, &d, &p, 10);
112+
else if (u < 100) n = digits(u, 1, &d, &p, 2);
113+
else if (u < 10000) n = digits(u, 100, &d, &p, 4);
114+
else if (u < 1000000) n = digits(u, 10000, &d, &p, 6);
115+
else n = digits(u, 1000000, &d, &p, 8);
116+
return itoa( u, p, d, n );
117+
}
118+
119+
char* itoa_32(int32_t i, char* p) {
120+
uint32_t u = i;
121+
if (i < 0) {
122+
*p++ = '-';
123+
u = -u;
124+
}
125+
return itoa_u32(u, p);
126+
}
127+
128+
char* itoa_u64(uint64_t u, char* p) {
129+
int d;
130+
131+
uint32_t lower = (uint32_t)u;
132+
if (lower == u) return itoa_u32(lower, p);
133+
134+
uint64_t upper = u / 1000000000;
135+
p = itoa_u64(upper, p);
136+
lower = u - (upper * 1000000000);
137+
d = lower / 100000000;
138+
p = out1('0'+d,p);
139+
return itoa( lower, p, d, 9 );
140+
}
141+
142+
char* itoa_64(int64_t i, char* p) {
143+
uint64_t u = i;
144+
if (i < 0) {
145+
*p++ = '-';
146+
u = -u;
147+
}
148+
return itoa_u64(u, p);
149+
}

itoa_ljust.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#ifndef ITOA_LJUST_H
2+
#define ITOA_LJUST_H
3+
4+
//=== itoa_ljust.h - Fast integer to ascii conversion
5+
//
6+
// Fast and simple integer to ASCII conversion:
7+
//
8+
// - 32 and 64-bit integers
9+
// - signed and unsigned
10+
// - user supplied buffer must be large enough for all decimal digits
11+
// in value plus minus sign if negative
12+
// - left-justified
13+
// - NUL terminated
14+
// - return value is pointer to NUL terminator
15+
//
16+
// Copyright (c) 2016 Arturo Martin-de-Nicolas
17+
18+
// https://github.com/amdn/itoa_ljust/
19+
//===----------------------------------------------------------------------===//
20+
21+
#include <stdint.h>
22+
23+
char* itoa_u32(uint32_t u, char* buffer);
24+
char* itoa_32( int32_t i, char* buffer);
25+
char* itoa_u64(uint64_t u, char* buffer);
26+
char* itoa_64( int64_t i, char* buffer);
27+
28+
#endif // ITOA_LJUST_H

memcached.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <unistd.h>
2020
#include <assert.h>
2121

22+
#include "itoa_ljust.h"
2223
#include "protocol_binary.h"
2324
#include "cache.h"
2425
#include "logger.h"

0 commit comments

Comments
 (0)