Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #164423 > unrolled thread

on an analogy for verifying whether another digit fits (into an unsigned type)

Started byMeredith Montgomery <mmontgomery@levado.to>
First post2022-01-15 23:27 -0300
Last post2022-01-28 22:25 -0300
Articles 20 on this page of 64 — 11 participants

Back to article view | Back to comp.lang.c


Contents

  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 →


#164488

FromBonita Montero <Bonita.Montero@gmail.com>
Date2022-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]


#164492

FromÖö Tiib <ootiib@hot.ee>
Date2022-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]


#164480

Fromscott@slp53.sl.home (Scott Lurndal)
Date2022-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]


#164484

FromBart <bc@freeuk.com>
Date2022-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]


#164485

Fromscott@slp53.sl.home (Scott Lurndal)
Date2022-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]


#164486

FromBart <bc@freeuk.com>
Date2022-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]


#164487

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2022-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]


#164490

FromBart <bc@freeuk.com>
Date2022-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]


#164491

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2022-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]


#164493

FromBart <bc@freeuk.com>
Date2022-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]


#164494

FromBart <bc@freeuk.com>
Date2022-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]


#164558

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2022-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]


#164560

FromBart <bc@freeuk.com>
Date2022-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]


#164561

FromLew Pitcher <lew.pitcher@digitalfreehold.ca>
Date2022-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]


#164562

FromBart <bc@freeuk.com>
Date2022-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]


#164563

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2022-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]


#164575

FromBart <bc@freeuk.com>
Date2022-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]


#164581

Fromscott@slp53.sl.home (Scott Lurndal)
Date2022-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]


#164592

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2022-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]


#164598

Fromscott@slp53.sl.home (Scott Lurndal)
Date2022-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