Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #164423 > unrolled thread
| Started by | Meredith Montgomery <mmontgomery@levado.to> |
|---|---|
| First post | 2022-01-15 23:27 -0300 |
| Last post | 2022-01-28 22:25 -0300 |
| Articles | 20 on this page of 64 — 11 participants |
Back to article view | Back to comp.lang.c
on an analogy for verifying whether another digit fits (into an unsigned type) Meredith Montgomery <mmontgomery@levado.to> - 2022-01-15 23:27 -0300
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Bart <bc@freeuk.com> - 2022-01-16 18:44 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Meredith Montgomery <mmontgomery@levado.to> - 2022-01-17 09:48 -0300
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-01-17 17:27 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) scott@slp53.sl.home (Scott Lurndal) - 2022-01-17 18:06 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-01-17 20:59 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) scott@slp53.sl.home (Scott Lurndal) - 2022-01-18 01:01 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Meredith Montgomery <mmontgomery@levado.to> - 2022-01-28 22:15 -0300
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-01-29 02:36 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Meredith Montgomery <mmontgomery@levado.to> - 2022-01-30 09:12 -0300
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-01-30 15:13 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Öö Tiib <ootiib@hot.ee> - 2022-01-16 12:15 -0800
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Meredith Montgomery <mmontgomery@levado.to> - 2022-01-17 09:53 -0300
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Meredith Montgomery <mmontgomery@levado.to> - 2022-01-17 10:12 -0300
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Bonita Montero <Bonita.Montero@gmail.com> - 2022-01-19 08:52 +0100
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Öö Tiib <ootiib@hot.ee> - 2022-01-19 06:08 -0800
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Bonita Montero <Bonita.Montero@gmail.com> - 2022-01-19 16:31 +0100
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Bonita Montero <Bonita.Montero@gmail.com> - 2022-01-19 18:02 +0100
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Bart <bc@freeuk.com> - 2022-01-19 18:27 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Bonita Montero <Bonita.Montero@gmail.com> - 2022-01-19 19:44 +0100
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Bonita Montero <Bonita.Montero@gmail.com> - 2022-01-20 08:08 +0100
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Öö Tiib <ootiib@hot.ee> - 2022-01-20 09:47 -0800
Re: on an analogy for verifying whether another digit fits (into an unsigned type) scott@slp53.sl.home (Scott Lurndal) - 2022-01-19 18:46 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Bart <bc@freeuk.com> - 2022-01-19 20:59 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) scott@slp53.sl.home (Scott Lurndal) - 2022-01-19 21:12 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Bart <bc@freeuk.com> - 2022-01-19 22:25 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-01-20 03:49 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Bart <bc@freeuk.com> - 2022-01-20 10:05 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-01-20 17:02 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Bart <bc@freeuk.com> - 2022-01-20 19:20 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Bart <bc@freeuk.com> - 2022-01-20 19:31 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-01-23 14:26 -0800
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Bart <bc@freeuk.com> - 2022-01-24 00:13 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2022-01-24 00:38 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Bart <bc@freeuk.com> - 2022-01-24 01:09 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-01-24 01:15 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Bart <bc@freeuk.com> - 2022-01-24 11:21 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) scott@slp53.sl.home (Scott Lurndal) - 2022-01-24 15:54 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-01-24 13:08 -0800
Re: on an analogy for verifying whether another digit fits (into an unsigned type) scott@slp53.sl.home (Scott Lurndal) - 2022-01-24 22:51 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2022-01-24 15:57 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Bart <bc@freeuk.com> - 2022-01-24 16:52 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Öö Tiib <ootiib@hot.ee> - 2022-01-24 10:17 -0800
Re: on an analogy for verifying whether another digit fits (into an unsigned type) scott@slp53.sl.home (Scott Lurndal) - 2022-01-24 18:23 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-01-24 13:15 -0800
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Bart <bc@freeuk.com> - 2022-01-24 11:51 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-01-23 17:38 -0800
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Bart <bc@freeuk.com> - 2022-01-24 11:22 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) scott@slp53.sl.home (Scott Lurndal) - 2022-01-24 15:51 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Bart <bc@freeuk.com> - 2022-01-24 22:03 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-01-24 15:33 -0800
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Bart <bc@freeuk.com> - 2022-01-25 00:09 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2022-01-24 21:14 -0800
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Manfred <invalid@invalid.add> - 2022-01-26 21:01 +0100
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Bart <bc@freeuk.com> - 2022-01-26 20:53 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Manfred <noname@add.invalid> - 2022-01-27 03:42 +0100
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-01-20 19:24 -0800
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Bonita Montero <Bonita.Montero@gmail.com> - 2022-01-21 08:07 +0100
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-01-21 06:01 -0800
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Bonita Montero <Bonita.Montero@gmail.com> - 2022-01-21 17:59 +0100
Re: on an analogy for verifying whether another digit fits (into an unsigned type) scott@slp53.sl.home (Scott Lurndal) - 2022-01-21 17:41 +0000
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Bonita Montero <Bonita.Montero@gmail.com> - 2022-01-21 19:26 +0100
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-01-21 17:12 -0800
Re: on an analogy for verifying whether another digit fits (into an unsigned type) Meredith Montgomery <mmontgomery@levado.to> - 2022-01-28 22:25 -0300
Page 2 of 4 — ← Prev page 1 [2] 3 4 Next page →
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2022-01-20 08:08 +0100 |
| Message-ID | <ssb1pb$nk6$1@dont-email.me> |
| In reply to | #164479 |
Am 19.01.2022 um 19:44 schrieb Bonita Montero:
> That's slower than the variants with intrinsics.
Here's a little benchmark:
#include <iostream>
#include <stdexcept>
#include <string>
#include <string>
#include <vector>
#include <random>
#include <sstream>
#include <chrono>
#include <cstring>
#include <immintrin.h>
using namespace std;
using namespace chrono;
unsigned long long parseUllIntrinsic( char const *str );
unsigned long long parseUllStd( char const *str );
unsigned long long parseUllBart( char const *str );
unsigned long long volatile vSum;
int main()
{
constexpr size_t N = 1000;
vector<string> rNums;
rNums.reserve( N );
mt19937_64 mt;
uniform_int_distribution<unsigned long long> uidValues( 0, -1 );
ostringstream oss;
for( size_t i = 0; i != N; ++i )
{
oss.str( "" );
oss << uidValues( mt );
rNums.emplace_back( oss.str() );
}
auto bench = [&]( unsigned long long (*parseUllFn)( char const *) ) ->
double
{
unsigned long long sum = 0;
auto start = high_resolution_clock::now();
for( size_t i = 0; i != 10'000; ++i )
for( string &str : rNums )
sum += parseUllFn( str.c_str() );
::vSum = sum;
return (int64_t)duration_cast<nanoseconds>(
high_resolution_clock::now() - start ).count() / (10'000.0 * N);
};
cout << "intrinsic: " << bench( parseUllIntrinsic ) << endl;
cout << "std: " << bench( parseUllStd ) << endl;
cout << "Bart: " << bench( parseUllBart ) << endl;
}
#if defined(_MSC_VER)
__declspec(noinline)
#elif defined(__GNUC__)
__attribute__((noinline))
#endif
unsigned long long parseUllIntrinsic( char const *str )
{
if( !*str )
return 0;
unsigned long long value = (unsigned char)*str++ - '0';
for( ; *str; ++str )
{
#if defined(__llvm__) || defined(__GNUC__)
if( __builtin_umulll_overflow( value, 10, &value ) )
goto overflow;
if( __builtin_uaddll_overflow( value, (unsigned char)*str - '0', &value) )
goto overflow;
#elif defined(_MSC_VER)
unsigned long long hi;
value = _mulx_u64( value, 10, &hi );
if( hi )
goto overflow;
// _addcarry_u64 specified but missing (MSVC 2022)
if( value + ((unsigned char)*str - '0') < value )
goto overflow;
value += (unsigned char)*str - '0';
#else
#error no intinsic version
#endif
}
return value;
overflow:
throw overflow_error( "parseUll() overflow" );
}
#if defined(_MSC_VER)
__declspec(noinline)
#elif defined(__GNUC__)
__attribute__((noinline))
#endif
unsigned long long parseUllStd( char const *str )
{
unsigned long long value;
if( !*str )
return 0;
value = (unsigned char)*str++ - '0';
for( ; *str; ++str )
{
if( value * 10 / 10 != value )
goto overflow;
value *= 10;
unsigned char digit = *str - '0';
if( value + digit < value )
goto overflow;
value += digit;
}
return value;
overflow:
throw overflow_error( "parseUll() overflow" );
}
#if defined(_MSC_VER)
__declspec(noinline)
#elif defined(__GNUC__)
__attribute__((noinline))
#endif
unsigned long long parseUllBart( char const *str )
{
size_t len = strlen( str );
unsigned long long value;
if( len > 20 || len == 20 && strcmp( str, "18446744073709551615" ) > 0 )
goto overflow;
if( !*str )
return 0;
value = (unsigned char)*str++ - '0';
while( *str )
value *= 10,
value += (unsigned char)*str++ - '0';
return value;
overflow:
throw overflow_error( "parseUll() overflow" );
}
Here are the MSVC-results:
intrinsic: 20.4304
std: 20.3481
Bart: 22.2739
The gcc/O2-results:
intrinsic: 20.4639
std: 20.7395
Bart: 23.3007
The clang++/O2-results:
intrinsic: 21.1037
std: 21.9567
Bart: 22.7341
[toc] | [prev] | [next] | [standalone]
| From | Öö Tiib <ootiib@hot.ee> |
|---|---|
| Date | 2022-01-20 09:47 -0800 |
| Message-ID | <f824df51-7eeb-478b-b064-227b08bd4c5dn@googlegroups.com> |
| In reply to | #164488 |
On Thursday, 20 January 2022 at 09:08:39 UTC+2, Bonita Montero wrote:
> Am 19.01.2022 um 19:44 schrieb Bonita Montero:
>
> > That's slower than the variants with intrinsics.
> Here's a little benchmark:
All those test functions do something strange compared to what OP's posted
code did. OP posted relatively reasonable function like that:
uint64_t array_to_uint64(char *s, uint64_t *u) {./*...*/}
For example to string "15A" that function returned 2 and put 15 into value
pointed by u. That made sense.
Your code however returns 167. That feels nonsense, where it was specified?
It does not matter at what speed a code gives such nonsense answers. At
least among my customers.
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2022-01-19 18:46 +0000 |
| Message-ID | <C0ZFJ.134459$Gco3.62864@fx01.iad> |
| In reply to | #164478 |
Bart <bc@freeuk.com> writes: >On 19/01/2022 17:02, Bonita Montero wrote: > >Complicated. I used the simpler **C** code below. It's runtime was 10% >slower than the C++ (that is, elapsed time of the 10,000 outer loop for >both). I just use strtoll. Why reinvent the wheel?
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2022-01-19 20:59 +0000 |
| Message-ID | <ss9u3b$jdr$1@dont-email.me> |
| In reply to | #164480 |
On 19/01/2022 18:46, Scott Lurndal wrote: > Bart <bc@freeuk.com> writes: >> On 19/01/2022 17:02, Bonita Montero wrote: > >> >> Complicated. I used the simpler **C** code below. It's runtime was 10% >> slower than the C++ (that is, elapsed time of the 10,000 outer loop for >> both). > > I just use strtoll. Why reinvent the wheel? It needs to be stroull() for this purpose, which is more elusive (gcc has it on Windows, but the two other compilers I have don't), As to why it's worth reinventing, if I use strtoull instead, then my benchmarks runs in 2.8 seconds instead of 0.28 seconds; it's much slower! Besides which, when I need to do this stuff, the requirements are more diverse (eg dealing with numeric separators, or determining whether the literal fits in i64, u64, i128, u128, or represents a big number).
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2022-01-19 21:12 +0000 |
| Message-ID | <X8%FJ.28$rU.26@fx34.iad> |
| In reply to | #164484 |
Bart <bc@freeuk.com> writes: >On 19/01/2022 18:46, Scott Lurndal wrote: >> Bart <bc@freeuk.com> writes: >>> On 19/01/2022 17:02, Bonita Montero wrote: >> >>> >>> Complicated. I used the simpler **C** code below. It's runtime was 10% >>> slower than the C++ (that is, elapsed time of the 10,000 outer loop for >>> both). >> >> I just use strtoll. Why reinvent the wheel? > >It needs to be stroull() for this purpose, which is more elusive (gcc >has it on Windows, but the two other compilers I have don't), > >As to why it's worth reinventing, if I use strtoull instead, then my >benchmarks runs in 2.8 seconds instead of 0.28 seconds; it's much slower! Does your benchmark measure anything useful? Very, very, very few application will have strtoull as a dominant performance driver.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2022-01-19 22:25 +0000 |
| Message-ID | <ssa342$rih$1@dont-email.me> |
| In reply to | #164485 |
On 19/01/2022 21:12, Scott Lurndal wrote: > Bart <bc@freeuk.com> writes: >> On 19/01/2022 18:46, Scott Lurndal wrote: >>> Bart <bc@freeuk.com> writes: >>>> On 19/01/2022 17:02, Bonita Montero wrote: >>> >>>> >>>> Complicated. I used the simpler **C** code below. It's runtime was 10% >>>> slower than the C++ (that is, elapsed time of the 10,000 outer loop for >>>> both). >>> >>> I just use strtoll. Why reinvent the wheel? >> >> It needs to be stroull() for this purpose, which is more elusive (gcc >> has it on Windows, but the two other compilers I have don't), >> >> As to why it's worth reinventing, if I use strtoull instead, then my >> benchmarks runs in 2.8 seconds instead of 0.28 seconds; it's much slower! > > Does your benchmark measure anything useful? Only text to binary conversion of numbers, but then nobody ever does that do that? Apart from processing textual formats such XML, HTML, source code of virtually every language, configuration files, database files, CDF/CSV and other data files. > > Very, very, very few application will have strtoull as a dominant > performance driver. Plenty of slow software about. Ignoring things like this adds up. But in the case of strtoull, there are other issues with it: * Not all compilers may recognise it * The performance depends on the library used Using your own routine for this simple task eliminates those variables. The timing I quoted was the worst: * gcc/strtoull on Windows: 2.8 seconds (for 1M conversions) * gcc/strtoull on WSL: 0.6 seconds * gcc/_strtoui64 on Windows (in msvcrt): 0.7 seconds * My parseull routine on Windows: 0.28/0.35 seconds (with/without length) The intention was anyway to match that complex C++ code, which was also the wrong language, and also took 10 times as long to compile.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2022-01-20 03:49 +0000 |
| Message-ID | <87tudz2his.fsf@bsb.me.uk> |
| In reply to | #164486 |
Bart <bc@freeuk.com> writes: > But in the case of strtoull, there are other issues with it: > > * Not all compilers may recognise it It's almost always library issue, not a compiler issue. Any implementation (compiler + library) that does not have it is a poor one since it's been standard for a long time now. > * The performance depends on the library used > > Using your own routine for this simple task eliminates those variables. > > The timing I quoted was the worst: > > * gcc/strtoull on Windows: 2.8 seconds (for 1M conversions) > > * gcc/strtoull on WSL: 0.6 seconds > > * gcc/_strtoui64 on Windows (in msvcrt): 0.7 seconds You keep citing figures with little useful information. What length numbers? What are these various (apparently slow) implementation of strtoull that you have managed to find? Calling them gcc/strtoull is not helpful. For 10^6 numbers with, on average, 18.3 digits, the strtoull on a recent Ubuntu install (glibc 2.34) does the conversions in 0.042 seconds (i5-8265U CPU). Is your machine really more than 10 times slower than my laptop? > * My parseull routine on Windows: 0.28/0.35 seconds (with/without > length) This one probably doesn't do the same job, so it's not a direct comparison. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2022-01-20 10:05 +0000 |
| Message-ID | <ssbc4i$9a0$1@dont-email.me> |
| In reply to | #164487 |
On 20/01/2022 03:49, Ben Bacarisse wrote: > Bart <bc@freeuk.com> writes: > >> But in the case of strtoull, there are other issues with it: >> >> * Not all compilers may recognise it > > It's almost always library issue, not a compiler issue. Any > implementation (compiler + library) that does not have it is a poor one > since it's been standard for a long time now. > >> * The performance depends on the library used >> >> Using your own routine for this simple task eliminates those variables. >> >> The timing I quoted was the worst: >> >> * gcc/strtoull on Windows: 2.8 seconds (for 1M conversions) >> >> * gcc/strtoull on WSL: 0.6 seconds >> >> * gcc/_strtoui64 on Windows (in msvcrt): 0.7 seconds > > You keep citing figures with little useful information. What length > numbers? What are these various (apparently slow) implementation of > strtoull that you have managed to find? Calling them gcc/strtoull is > not helpful. > The full program is here: https://github.com/sal55/langs/blob/master/parseull.c You need to uncomment the routine you want in the inner loop. The numbers are the ones generated with BM's program. Timings are elapsed time from running the program, measured externally. > For 10^6 numbers with, on average, 18.3 digits, the strtoull on a recent > Ubuntu install (glibc 2.34) does the conversions in 0.042 seconds > (i5-8265U CPU). Is your machine really more than 10 times slower than > my laptop? Sorry, that was my mistake: it's 10^7 conversions (originally 10^6 in the C++ code but that was too quick to easily measure). >> * My parseull routine on Windows: 0.28/0.35 seconds (with/without >> length) > > This one probably doesn't do the same job, so it's not a direct > comparison. It was supposed to do the same job as BM's program: take a string containing only digits and convert them while checking for overflows. Although mine won't allow leading zeros if the overflow check is to work; that would slow it down slightly to eliminate them.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2022-01-20 17:02 +0000 |
| Message-ID | <87ilue2vda.fsf@bsb.me.uk> |
| In reply to | #164490 |
Bart <bc@freeuk.com> writes: > On 20/01/2022 03:49, Ben Bacarisse wrote: >> Bart <bc@freeuk.com> writes: >>> * My parseull routine on Windows: 0.28/0.35 seconds (with/without >>> length) >> >> This one probably doesn't do the same job, so it's not a direct >> comparison. > > It was supposed to do the same job as BM's program: take a string > containing only digits and convert them while checking for overflows. Right. But it does not do the same job as the other functions you gave timings for /in the post I replied to/. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2022-01-20 19:20 +0000 |
| Message-ID | <ssccm5$mmo$1@dont-email.me> |
| In reply to | #164491 |
On 20/01/2022 17:02, Ben Bacarisse wrote:
> Bart <bc@freeuk.com> writes:
>
>> On 20/01/2022 03:49, Ben Bacarisse wrote:
>>> Bart <bc@freeuk.com> writes:
>
>>>> * My parseull routine on Windows: 0.28/0.35 seconds (with/without
>>>> length)
>>>
>>> This one probably doesn't do the same job, so it's not a direct
>>> comparison.
>>
>> It was supposed to do the same job as BM's program: take a string
>> containing only digits and convert them while checking for overflows.
>
> Right. But it does not do the same job as the other functions you gave
> timings for /in the post I replied to/.
OK. Maybe you should ask Scott Lurndal why /he/ brought up strtoll().
The implication was they they did the same kind of thing, namely convert
a string of digits to an integer.
I suggested that among several reasons why a custom routine might be
used, was performance, even if they differ in features.
However, I've created a version of my routine which is more in line with
how strtoull etc work (but I don't know the full spec), shown below.
This version is still 50% faster than the fastest stroull routine on my
machine.
(One reason may be that it is hard-coded for base-10. If so, then that
is an argument for creating your own dedicated base-10 version.)
-----------------------------------------------
typedef unsigned long long u64;
u64 parseull(char* s, char** send) {
int length,neg=0;
while (*s==' ' || *s=='\t' ) ++s; // leading spaces
if (*s=='-') {neg=1; ++s;} // optional signs
else if (*s=='+') ++s;
while (*s=='0' && *(s+1)=='0') ++s; // leading zeros
length=0;
*send=s;
while (**send>='0' && **send<='9') ++(*send);
length=*send-s;
if (length==0) return -1; // u64.max on error
if (length>20) return -1;
if (length==20 && strncmp(s, "18446744073709551615",20)>0)
return -1;
u64 a=*s -'0';
while (--length) {a=a*10+*++s-'0';};
if (neg) return -a;
return a;
}
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2022-01-20 19:31 +0000 |
| Message-ID | <sscdb1$r1m$1@dont-email.me> |
| In reply to | #164493 |
On 20/01/2022 19:20, Bart wrote:
> -----------------------------------------------
> typedef unsigned long long u64;
>
> u64 parseull(char* s, char** send) {
> int length,neg=0;
>
> while (*s==' ' || *s=='\t' ) ++s; // leading spaces
> if (*s=='-') {neg=1; ++s;} // optional signs
> else if (*s=='+') ++s;
> while (*s=='0' && *(s+1)=='0') ++s; // leading zeros
That's not quite right, as it will leave 1 leading zero; better:
while (*s=='0' && (*(s+1)>='1' && *(s+1)<='9')) ++s;
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2022-01-23 14:26 -0800 |
| Message-ID | <87pmoixf59.fsf@nosuchdomain.example.com> |
| In reply to | #164484 |
Bart <bc@freeuk.com> writes:
> On 19/01/2022 18:46, Scott Lurndal wrote:
>> Bart <bc@freeuk.com> writes:
>>> On 19/01/2022 17:02, Bonita Montero wrote:
>>> Complicated. I used the simpler **C** code below. It's runtime was 10%
>>> slower than the C++ (that is, elapsed time of the 10,000 outer loop for
>>> both).
>> I just use strtoll. Why reinvent the wheel?
>
> It needs to be stroull() for this purpose, which is more elusive (gcc
> has it on Windows, but the two other compilers I have don't),
gcc does not provide strtoll() or strtoull(). Both are provided by the
library, not by the compiler. (And both were introduced in C99, so I'd
be at least mildly surprised by an implementation that provides one
but not the other.)
I know you're tired of people pointing out that the compiler (gcc
in this case) does not provide library functions. The solution is
for you to stop making that mistake. Or should I assume you enjoy
these arguments?
[...]
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2022-01-24 00:13 +0000 |
| Message-ID | <sskqvb$im7$1@dont-email.me> |
| In reply to | #164558 |
On 23/01/2022 22:26, Keith Thompson wrote: > Bart <bc@freeuk.com> writes: >> On 19/01/2022 18:46, Scott Lurndal wrote: >>> Bart <bc@freeuk.com> writes: >>>> On 19/01/2022 17:02, Bonita Montero wrote: >>>> Complicated. I used the simpler **C** code below. It's runtime was 10% >>>> slower than the C++ (that is, elapsed time of the 10,000 outer loop for >>>> both). >>> I just use strtoll. Why reinvent the wheel? >> >> It needs to be stroull() for this purpose, which is more elusive (gcc >> has it on Windows, but the two other compilers I have don't), > > gcc does not provide strtoll() or strtoull(). Both are provided by the > library, not by the compiler. (And both were introduced in C99, so I'd > be at least mildly surprised by an implementation that provides one > but not the other.) > > I know you're tired of people pointing out that the compiler (gcc > in this case) does not provide library functions. The solution is > for you to stop making that mistake. Or should I assume you enjoy > these arguments? gcc/tdm compiles programs using strtoull. bcc/tcc fail with a link error, unless I include this line: #define strtoull _strtoui64 but then gcc will complain about it. Actually why that is the case, I don't know, don't care, and probably no else cares who just installs a 'bundle' without wanting to trace and check the provenance of each library function that it comes with. The above is enough for me to think twice about using strtoull in a project.
[toc] | [prev] | [next] | [standalone]
| From | Lew Pitcher <lew.pitcher@digitalfreehold.ca> |
|---|---|
| Date | 2022-01-24 00:38 +0000 |
| Message-ID | <sskseu$if4$1@dont-email.me> |
| In reply to | #164560 |
On Mon, 24 Jan 2022 00:13:32 +0000, Bart wrote: > On 23/01/2022 22:26, Keith Thompson wrote: >> Bart <bc@freeuk.com> writes: >>> On 19/01/2022 18:46, Scott Lurndal wrote: >>>> Bart <bc@freeuk.com> writes: >>>>> On 19/01/2022 17:02, Bonita Montero wrote: >>>>> Complicated. I used the simpler **C** code below. It's runtime was 10% >>>>> slower than the C++ (that is, elapsed time of the 10,000 outer loop for >>>>> both). >>>> I just use strtoll. Why reinvent the wheel? >>> >>> It needs to be stroull() for this purpose, which is more elusive (gcc >>> has it on Windows, but the two other compilers I have don't), >> >> gcc does not provide strtoll() or strtoull(). Both are provided by the >> library, not by the compiler. (And both were introduced in C99, so I'd >> be at least mildly surprised by an implementation that provides one >> but not the other.) >> >> I know you're tired of people pointing out that the compiler (gcc >> in this case) does not provide library functions. The solution is >> for you to stop making that mistake. Or should I assume you enjoy >> these arguments? > > gcc/tdm compiles programs using strtoull. > > bcc/tcc fail with a link error, unless I include this line: > > #define strtoull _strtoui64 > > but then gcc will complain about it. Countless generations of programmers have found a sensible way to handle such conflicts by using conditional compilation. strtoull() has been defined as being part of the C99 standard library, and before that, part of the POSIX.1-2001 and POSIX.1-2001 Unix standard libraries. A simple macro test of the value of __STDC_VERSION__, and setting of the appropriate pre-C99 macros should be all that is necessary to properly access strtoull(). Something like #if (__STDC_VERSION__ < 199901l) //do whatever it takes to properly define strtoull() for this platform #endif (note, the above "do whatever" might include such things as testing macros to determine the platform and take appropriate action, as in #ifdef WIN32 #define strtoull _strtoui64 #endif or defining macros to force platform-specific libraries, like #define _SVID_SOURCE [snip] > The above is enough for me to think twice about using strtoull in a project. Your loss, I guess. -- Lew Pitcher "In Skills, We Trust"
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2022-01-24 01:09 +0000 |
| Message-ID | <ssku8l$2uq$1@dont-email.me> |
| In reply to | #164561 |
On 24/01/2022 00:38, Lew Pitcher wrote: > On Mon, 24 Jan 2022 00:13:32 +0000, Bart wrote: > >> On 23/01/2022 22:26, Keith Thompson wrote: >>> Bart <bc@freeuk.com> writes: >>>> On 19/01/2022 18:46, Scott Lurndal wrote: >>>>> Bart <bc@freeuk.com> writes: >>>>>> On 19/01/2022 17:02, Bonita Montero wrote: >>>>>> Complicated. I used the simpler **C** code below. It's runtime was 10% >>>>>> slower than the C++ (that is, elapsed time of the 10,000 outer loop for >>>>>> both). >>>>> I just use strtoll. Why reinvent the wheel? >>>> >>>> It needs to be stroull() for this purpose, which is more elusive (gcc >>>> has it on Windows, but the two other compilers I have don't), >>> >>> gcc does not provide strtoll() or strtoull(). Both are provided by the >>> library, not by the compiler. (And both were introduced in C99, so I'd >>> be at least mildly surprised by an implementation that provides one >>> but not the other.) >>> >>> I know you're tired of people pointing out that the compiler (gcc >>> in this case) does not provide library functions. The solution is >>> for you to stop making that mistake. Or should I assume you enjoy >>> these arguments? >> >> gcc/tdm compiles programs using strtoull. >> >> bcc/tcc fail with a link error, unless I include this line: >> >> #define strtoull _strtoui64 >> >> but then gcc will complain about it. > > Countless generations of programmers have found a sensible way to handle such > conflicts by using conditional compilation. > > strtoull() has been defined as being part of the C99 standard library, and > before that, part of the POSIX.1-2001 and POSIX.1-2001 Unix standard libraries. > A simple macro test of the value of __STDC_VERSION__, and setting of the appropriate > pre-C99 macros should be all that is necessary to properly access strtoull(). > > Something like > #if (__STDC_VERSION__ < 199901l) > //do whatever it takes to properly define strtoull() for this platform > #endif > > (note, the above "do whatever" might include such things as testing macros > to determine the platform and take appropriate action, as in > #ifdef WIN32 > #define strtoull _strtoui64 > #endif > or defining macros to force platform-specific libraries, like > #define _SVID_SOURCE If you're an implementer creating headers for a C compiler, then you should just declare then properly. I just have in mine; it took a minute or so (after previously finding out that MS uses that different naming). But I can't do it for tcc or any other compiler that might have an issue. And if you're not an implementer, then that's a lot of clutter to go into your application's headers just to pander for one or two compilers. It's the sort of think I absolutely hate when poking arond application headers, trying to figure why it doesn't work, because it's special-casing some specific compilers, which will then exclude mine. You might as well just implement a suitable function, then it'll run anywhere, might be faster as I found, and could be made with a sweeter interface.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2022-01-24 01:15 +0000 |
| Message-ID | <87wniq0w8m.fsf@bsb.me.uk> |
| In reply to | #164560 |
Bart <bc@freeuk.com> writes: > On 23/01/2022 22:26, Keith Thompson wrote: >> Bart <bc@freeuk.com> writes: >>> On 19/01/2022 18:46, Scott Lurndal wrote: >>>> Bart <bc@freeuk.com> writes: >>>>> On 19/01/2022 17:02, Bonita Montero wrote: >>>>> Complicated. I used the simpler **C** code below. It's runtime was 10% >>>>> slower than the C++ (that is, elapsed time of the 10,000 outer loop for >>>>> both). >>>> I just use strtoll. Why reinvent the wheel? >>> >>> It needs to be stroull() for this purpose, which is more elusive (gcc >>> has it on Windows, but the two other compilers I have don't), >> gcc does not provide strtoll() or strtoull(). Both are provided by the >> library, not by the compiler. (And both were introduced in C99, so I'd >> be at least mildly surprised by an implementation that provides one >> but not the other.) >> I know you're tired of people pointing out that the compiler (gcc >> in this case) does not provide library functions. The solution is >> for you to stop making that mistake. Or should I assume you enjoy >> these arguments? > > gcc/tdm compiles programs using strtoull. > > bcc/tcc fail with a link error, My tcc-based C installation handles it fine. That's because, as you must know, it's not a compiler issue. > unless I include this line: > > #define strtoull _strtoui64 Which, of course, means "unless I don't use strtoull". > but then gcc will complain about it. > > Actually why that is the case, I don't know, don't care, and probably > no else cares who just installs a 'bundle' without wanting to trace > and check the provenance of each library function that it comes with. I'd hope it's rare to not want to know what's going on. > The above is enough for me to think twice about using strtoull in a > project. If your code must work with non-standard C implementations, then there might well be a whole raft of things you should avoid. But since you seem to use C a lot, wouldn't it be better either to try to fix your tcc installation or to simply uninstall it? -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2022-01-24 11:21 +0000 |
| Message-ID | <ssm23g$q5s$1@dont-email.me> |
| In reply to | #164563 |
On 24/01/2022 01:15, Ben Bacarisse wrote:
> Bart <bc@freeuk.com> writes:
>
>> On 23/01/2022 22:26, Keith Thompson wrote:
>>> Bart <bc@freeuk.com> writes:
>>>> On 19/01/2022 18:46, Scott Lurndal wrote:
>>>>> Bart <bc@freeuk.com> writes:
>>>>>> On 19/01/2022 17:02, Bonita Montero wrote:
>>>>>> Complicated. I used the simpler **C** code below. It's runtime was 10%
>>>>>> slower than the C++ (that is, elapsed time of the 10,000 outer loop for
>>>>>> both).
>>>>> I just use strtoll. Why reinvent the wheel?
>>>>
>>>> It needs to be stroull() for this purpose, which is more elusive (gcc
>>>> has it on Windows, but the two other compilers I have don't),
>>> gcc does not provide strtoll() or strtoull(). Both are provided by the
>>> library, not by the compiler. (And both were introduced in C99, so I'd
>>> be at least mildly surprised by an implementation that provides one
>>> but not the other.)
>>> I know you're tired of people pointing out that the compiler (gcc
>>> in this case) does not provide library functions. The solution is
>>> for you to stop making that mistake. Or should I assume you enjoy
>>> these arguments?
>>
>> gcc/tdm compiles programs using strtoull.
>>
>> bcc/tcc fail with a link error,
>
> My tcc-based C installation handles it fine. That's because, as you
> must know, it's not a compiler issue.
c:\c>type c.c
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char* p;
printf("%llu\n", strtoull("1234", &p, 10));
}
c:\c>tcc c.c
tcc: error: undefined symbol 'strtoull'
c:\c>tcc -c c.c
c:\c>tcc -v
tcc version 0.9.27 (x86_64 Windows)
It looks like a link issue with tcc to me. As I said this was on
Windows. tcc appears to use msvcrt.dll, because when I add that define,
and look at the resulting exe, it says:
Name: msvcrt.dll
Import Addr RVA: 2038
Import: 20e3 0 _strtoui64
Import: 20f0 0 printf
Import: 20f9 0 __set_app_type
....
Maybe some people spend at lot of time telling their compilers exactly
which libraries to use for standard functions of C; I just use the
supplied compiler or driver program.
Since all C compilers that I've used will do the whole job of source ->
binary just by invoking that front end.
So, what version of tcc do you have, and what special thing do you have
to do to make it work?
If you're on Linux, that doesn't count as the standard library is
unlikely to use MS's _strtoui64 name for that function.
This is what I originally said:
"...(gcc has it on Windows, but the two other compilers I have don't)"
>> unless I include this line:
>>
>> #define strtoull _strtoui64
>
> Which, of course, means "unless I don't use strtoull".
It's better not to. If I were to post code anywhere that used it, then
at least some people trying it wouldn't be able to build it. And I'm not
having /my/ code full of those implementation-specific conditional
blocks that I despise.
For the same reason, I tend not to write shared code that uses '$' in
identifiers, because tcc doesn't support it.
> If your code must work with non-standard C implementations, then there
> might well be a whole raft of things you should avoid. But since you
> seem to use C a lot, wouldn't it be better either to try to fix your tcc
> installation or to simply uninstall it?
What do you mean by fix? Fixing my tcc doesn't help people compiling my
code unless everybody fixes theirs too.
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2022-01-24 15:54 +0000 |
| Message-ID | <tYzHJ.11748$1_.11324@fx37.iad> |
| In reply to | #164575 |
Bart <bc@freeuk.com> writes: > c:\c>tcc c.c > tcc: error: undefined symbol 'strtoull' strtoull is a POSIX symbol. If the tcc implementation you are using supports POSIX, then you've likely misconfigured tcc, otherwise you're tilting at windmills.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2022-01-24 13:08 -0800 |
| Message-ID | <87czkgon8u.fsf@nosuchdomain.example.com> |
| In reply to | #164581 |
scott@slp53.sl.home (Scott Lurndal) writes:
> Bart <bc@freeuk.com> writes:
>
>> c:\c>tcc c.c
>> tcc: error: undefined symbol 'strtoull'
>
> strtoull is a POSIX symbol. If the tcc implementation you
> are using supports POSIX, then you've likely misconfigured tcc,
> otherwise you're tilting at windmills.
I'm not sure what you mean by POSIX symbol. In C99 and later, strtoll
and strtoull are both defined by ISO C, and will be supported by any
conforming (hosted) implementation. Neither was defined by C90. I
suppose earlier editions of POSIX may have defined strtoll and strtoull
for pre-C99 compilers, but they depend on the long long and unsigned
long long types.
Did pre-C99 versions of POSIX (optionally?) specify long long and
unsigned long long before ISO C did?
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2022-01-24 22:51 +0000 |
| Message-ID | <T3GHJ.875$dV.689@fx44.iad> |
| In reply to | #164592 |
Keith Thompson <Keith.S.Thompson+u@gmail.com> writes: >scott@slp53.sl.home (Scott Lurndal) writes: >> Bart <bc@freeuk.com> writes: >> >>> c:\c>tcc c.c >>> tcc: error: undefined symbol 'strtoull' >> >> strtoull is a POSIX symbol. If the tcc implementation you >> are using supports POSIX, then you've likely misconfigured tcc, >> otherwise you're tilting at windmills. > >I'm not sure what you mean by POSIX symbol. In C99 and later, strtoll >and strtoull are both defined by ISO C, and will be supported by any >conforming (hosted) implementation. Neither was defined by C90. I >suppose earlier editions of POSIX may have defined strtoll and strtoull >for pre-C99 compilers, but they depend on the long long and unsigned >long long types. POSIX generally incorporates a C standard by reference, and we had implemented (circa 1989) the strto[u]ll functions in our versions of Unix for the Motorla 88100. My early specs are in storage, so I can't refer back to them to see when 1003.4 or X/Open adopted them.
[toc] | [prev] | [next] | [standalone]
Page 2 of 4 — ← Prev page 1 [2] 3 4 Next page →
Back to top | Article view | comp.lang.c
csiph-web