Discussion:
How to check a string is empty?
Lambda
2010-04-08 10:27:54 UTC
Permalink
Some functions that return string will return empty string when
something is wrong.
To check a string is empty or not, there are several ways:
len(str) == 0 or
str == ""
...
Which one is preferred?
--
To unsubscribe, reply using "remove me" as the subject.
Kees
2010-04-08 11:01:33 UTC
Permalink
I prefer

str+"badgerbadgerbadger" == "badgerbadgerbadger"

But that's just me I suppose :-)
Post by Lambda
Some functions that return string will return empty string when
something is wrong.
len(str) == 0 or
str == ""
...
Which one is preferred?
--
To unsubscribe, reply using "remove me" as the subject.
peterGo
2010-04-08 14:11:48 UTC
Permalink
Kees,
Post by Kees
I prefer
str+"badgerbadgerbadger" == "badgerbadgerbadger"
That is a very inefficient way to test for len(str) == 0

Strings are immutable. A new string is created, which is the
concatenation of the variable str and the string literal. Then, if the
string lengths are equal, which they would be for var str = "", each
byte of the UTF-8 string is compared for equality. There are calls to
runtime.catstring and runtime.cmpstring.

Peter
Post by Kees
I prefer
str+"badgerbadgerbadger" == "badgerbadgerbadger"
But that's just me I suppose :-)
Post by Lambda
Some functions that return string will return empty string when
something is wrong.
len(str) == 0 or
str == ""
...
Which one is preferred?
--
To unsubscribe, reply using "remove me" as the subject.
chris dollin
2010-04-08 14:17:44 UTC
Permalink
Post by peterGo
Kees,
Post by Kees
I prefer
str+"badgerbadgerbadger" == "badgerbadgerbadger"
That is a very inefficient way to test for len(str) == 0
I think it was supposed to be a (shell-inspired?) joke.
--
Chris "stess on 'supposed'" Dollin
--
To unsubscribe, reply using "remove me" as the subject.
Joan Miller
2010-04-08 11:44:34 UTC
Permalink
It's faster and simple to use
str == ""

Before of that, you could want to remove blank spaces:
strings.TrimSpace(str)
Post by Lambda
Some functions that return string will return empty string when
something is wrong.
len(str) == 0 or
str == ""
...
Which one is preferred?
--
To unsubscribe, reply using "remove me" as the subject.
chris dollin
2010-04-08 11:48:06 UTC
Permalink
Post by Joan Miller
It's faster
Than what? len(str) == 0?

Why do you think so?
Post by Joan Miller
and simple to use str == ""
It's certainly more /obvious/ to use str == "". (I'd expect
the compiler to compile that into the same code as
len(str)==0, myself.)
--
Chris "allusive" Dollin
--
To unsubscribe, reply using "remove me" as the subject.
Joan Miller
2010-04-08 11:56:57 UTC
Permalink
Post by chris dollin
Post by Joan Miller
It's faster
Than what? len(str) == 0?
Why do you think so?
Because it calls to the function `len` to get its size. Using a call
to a function will be something slower than using directly the code to
get the result.
--
To unsubscribe, reply using "remove me" as the subject.
Alexander Surma
2010-04-08 12:03:32 UTC
Permalink
Post by Joan Miller
Because it calls to the function `len` to get its size. Using a call
to a function will be something slower than using directly the code to
get the result
Actually, this doesn't have to be true. As far as a I know, go-strings
are (internally) a struct containing the length of the string and a
rune-array. So comparing to strings (i.e. traversing both strings) is
considerably *slower* than comparing length. But I'd assume that the
go developers were smart enough to make a length-comparison before
traversing both strings.

Surma
--
To unsubscribe, reply using "remove me" as the subject.
peterGo
2010-04-08 14:45:58 UTC
Permalink
Alexander,
Post by Alexander Surma
As far as a I know, go-strings
are (internally) a struct containing the length of the string and a
rune-array.
In Go, strings are encoded, in variable length form, as UTF-8, which
stored in a byte array. Therefore, the length of the string is
actually the number of bytes used to store the UTF-8 string, not the
number of Unicode characters or code points.

Peter
Post by Alexander Surma
Post by Joan Miller
Because it calls to the function `len` to get its size. Using a call
to a function will be something slower than using directly the code to
get the result
Actually, this doesn't have to be true. As far as a I know, go-strings
are (internally) a struct containing the length of the string and a
rune-array. So comparing to strings (i.e. traversing both strings) is
considerably *slower* than comparing length. But I'd assume that the
go developers were smart enough to make a length-comparison before
traversing both strings.
Surma
--
To unsubscribe, reply using "remove me" as the subject.
chris dollin
2010-04-08 12:06:41 UTC
Permalink
Post by Joan Miller
Post by chris dollin
Post by Joan Miller
It's faster
Than what? len(str) == 0?
Why do you think so?
Because it calls to the function `len` to get its size.
len is a builtin. I don't expect any function calls to be involved.

... func strlen( s string ) int { return len(s) } ...

... 8g -S len.go > xxx ... xvi xxx ...

Can't see a function call there.
--
Chris "allusive" Dollin
--
To unsubscribe, reply using "remove me" as the subject.
peterGo
2010-04-08 13:51:11 UTC
Permalink
Joan,
Post by Joan Miller
Because it calls to the function `len` to get its size. Using a call
to a function will be something slower than using directly the code to
get the result.
The question is about the facts, not your opinion.

if len(s) == 0 {
}

MOVL s+-32(SP),BX
CMPL BX,$0
JNE ,6

Peter
Post by Joan Miller
Post by chris dollin
Post by Joan Miller
It's faster
Than what? len(str) == 0?
Why do you think so?
Because it calls to the function `len` to get its size. Using a call
to a function will be something slower than using directly the code to
get the result.
--
To unsubscribe, reply using "remove me" as the subject.
Joan Miller
2010-04-08 14:13:52 UTC
Permalink
Post by peterGo
Joan,
Post by Joan Miller
Because it calls to the function `len` to get its size. Using a call
to a function will be something slower than using directly the code to
get the result.
The question is about the facts, not your opinion.
Those facts are valid for whatever another function. This case is an
exception because `len` is a builtin function.
--
To unsubscribe, reply using "remove me" as the subject.
Peter Bourgon
2010-04-08 14:22:42 UTC
Permalink
Post by Joan Miller
Post by peterGo
The question is about the facts, not your opinion.
Those facts are valid for whatever another function. This case is an
exception because `len` is a builtin function.
Even if len weren't a builtin function, testing s == "" requires an
O(n) traversal of s, which can easily be more costly than a function
call. Further, in many languages, even the == operator by itself may
have the same cost as a function call.
chris dollin
2010-04-08 14:28:18 UTC
Permalink
Post by Peter Bourgon
Post by Joan Miller
Post by peterGo
The question is about the facts, not your opinion.
Those facts are valid for whatever another function. This case is an
exception because `len` is a builtin function.
Even if len weren't a builtin function, testing s == "" requires an
O(n) traversal of s,
Not if s has its length exposed. A single comparison will do
(and in fact that's what 8g does).

For general string equality, yes; the cost of /fetching data/
may dwarf the cost of calling a function, especially if it's
in the cache already.
--
Chris "allusive" Dollin
--
To unsubscribe, reply using "remove me" as the subject.
chris dollin
2010-04-08 15:07:55 UTC
Permalink
Post by chris dollin
Post by Peter Bourgon
Post by Joan Miller
Post by peterGo
The question is about the facts, not your opinion.
Those facts are valid for whatever another function. This case is an
exception because `len` is a builtin function.
Even if len weren't a builtin function, testing s == "" requires an
O(n) traversal of s,
Not if s has its length exposed. A single comparison will do
(and in fact that's what 8g does).
It looks like I have to eat at least some of my words; vim had
kindly started me off part-way down the assembler file. I
think the preamble is all string copying and the core is the
single comparison, but at the moment ...
--
Chris "mr face, meet mr egg" Dollin
--
To unsubscribe, reply using "remove me" as the subject.
peterGo
2010-04-08 15:03:39 UTC
Permalink
Peter,

If the lengths of the strings are the same, s == "some string"
comparison time is O(n), where n is the number of bytes for variable
length UTF-8 encoded strings. If the string lengths differ, then only
the string lengths need be compared for equality; string comparison
time is zero.

For example, runtime.cmpstring.
http://golang.org/src/pkg/runtime/string.cgo

Peter
Post by Peter Bourgon
Post by Joan Miller
Post by peterGo
The question is about the facts, not your opinion.
Those facts are valid for whatever another function. This case is an
exception because `len` is a builtin function.
Even if len weren't a builtin function, testing s == "" requires an
O(n) traversal of s, which can easily be more costly than a function
call. Further, in many languages, even the == operator by itself may
have the same cost as a function call.
--
To unsubscribe, reply using "remove me" as the subject.
chris dollin
2010-04-08 14:22:45 UTC
Permalink
Post by Joan Miller
Post by peterGo
Joan,
Post by Joan Miller
Because it calls to the function `len` to get its size. Using a call
to a function will be something slower than using directly the code to
get the result.
The question is about the facts, not your opinion.
Those facts are valid for whatever another function. This case is an
exception because `len` is a builtin function.
This case is the one that was being discussed.

(And there are more built-in functions than `len`.)

(And compilers are pretty much free to inline /any/ function if
they [1] think that will produced better results. Just because it
/looks/ like a function call doesn't mean it's implemented with
CALL and RETURN instructions, or that it uses any extra
stack, or that there are any transfers of control.)
--
Chris "mov pc, r14" Dollin
--
To unsubscribe, reply using "remove me" as the subject.
peterGo
2010-04-08 14:27:36 UTC
Permalink
Chris,
Post by chris dollin
It's certainly more /obvious/ to use str == "". (I'd expect
the compiler to compile that into the same code as
len(str)==0, myself.)
For 6g, you are going to be disappointed. If you ask for a string
comparison, that's what you get: a call to runtime.cmpstring.

Peter
Post by chris dollin
Post by Joan Miller
It's faster
Than what? len(str) == 0?
Why do you think so?
Post by Joan Miller
and simple to use str == ""
 It's certainly more /obvious/ to use str == "". (I'd expect
the compiler to compile that into the same code as
len(str)==0, myself.)
--
Chris "allusive" Dollin
--
To unsubscribe, reply using "remove me" as the subject.
peterGo
2010-04-08 14:00:27 UTC
Permalink
Lambda,

In Go, the underlying representation of a string includes a byte array
to store the string; the byte array includes its length. len(str) ==
0 is very efficient. For example.

var s string = ""
if len(s) == 0 {
}

translates to something like

MOVL s+-32(SP),BX
CMPL BX,$0
JNE ,6

Peter
Post by Lambda
Some functions that return string will return empty string when
something is wrong.
len(str) == 0 or
str == ""
...
Which one is preferred?
--
To unsubscribe, reply using "remove me" as the subject.
Joan Miller
2010-04-08 14:57:09 UTC
Permalink
var s string = ""
if s == "" {
}

translates to something like:

0007 (test2.go:5) LEAQ s+-16(SP),SI
0008 (test2.go:5) LEAQ (SP),DI
0009 (test2.go:5) MOVSQ ,
0010 (test2.go:5) MOVSQ ,
Post by peterGo
Lambda,
In Go, the underlying representation of a string includes a byte array
to store the string; the byte array includes its length.  len(str) ==
0 is very efficient.  For example.
var s string = ""
if len(s) == 0 {
}
translates to something like
MOVL    s+-32(SP),BX
CMPL    BX,$0
JNE     ,6
Peter
Post by Lambda
Some functions that return string will return empty string when
something is wrong.
len(str) == 0 or
str == ""
...
Which one is preferred?
--
To unsubscribe, reply using "remove me" as the subject.
Joan Miller
2010-04-08 15:00:45 UTC
Permalink
Sorry, it's larger:

0007 (test2.go:5) LEAQ s+-16(SP),SI
0008 (test2.go:5) LEAQ (SP),DI
0009 (test2.go:5) MOVSQ ,
0010 (test2.go:5) MOVSQ ,
0011 (test2.go:5) LEAQ go.string.""+0(SB),SI
0012 (test2.go:5) LEAQ 16(SP),DI
0013 (test2.go:5) MOVSQ ,
0014 (test2.go:5) MOVSQ ,
0015 (test2.go:5) CALL ,runtime.cmpstring+0(SB)
0016 (test2.go:5) MOVL 32(SP),BX
0017 (test2.go:5) CMPL BX,$0
0018 (test2.go:5) JNE ,6
---
Ok. Using `len(str)==0` is a lot of faster than `str == ""`
Post by peterGo
var s string = ""
if s == "" {
}
0007 (test2.go:5) LEAQ    s+-16(SP),SI
0008 (test2.go:5) LEAQ    (SP),DI
0009 (test2.go:5) MOVSQ   ,
0010 (test2.go:5) MOVSQ   ,
Post by peterGo
Lambda,
In Go, the underlying representation of a string includes a byte array
to store the string; the byte array includes its length.  len(str) ==
0 is very efficient.  For example.
var s string = ""
if len(s) == 0 {
}
translates to something like
MOVL    s+-32(SP),BX
CMPL    BX,$0
JNE     ,6
Peter
Post by Lambda
Some functions that return string will return empty string when
something is wrong.
len(str) == 0 or
str == ""
...
Which one is preferred?
--
To unsubscribe, reply using "remove me" as the subject.
Joan Miller
2010-04-08 15:05:29 UTC
Permalink
Post by peterGo
Lambda,
In Go, the underlying representation of a string includes a byte array
to store the string; the byte array includes its length.  len(str) ==
0 is very efficient.  For example.
var s string = ""
if len(s) == 0 {
}
translates to something like
MOVL    s+-32(SP),BX
CMPL    BX,$0
JNE     ,6
It's something more but it follows being shorter than the another one

0005 (test.go:5) JMP ,7
0006 (test.go:5) JMP ,16
0007 (test.go:5) MOVL s+-8(SP),BX
0008 (test.go:5) CMPL BX,$0
0009 (test.go:5) JNE ,6
--
To unsubscribe, reply using "remove me" as the subject.
peterGo
2010-04-08 15:25:07 UTC
Permalink
Lanbda,
Post by Lambda
Some functions that return string will return empty string when
something is wrong.
That should rarely be true in Go. Go allows for multiple return
values, therefore, the "comma err" or "comma ok" idiom is used; the
error is returned separately.

For example, from the strconv package,

func Unquote(s string) (t string, err os.Error)

Unquote interprets s as a single-quoted, double-quoted, or backquoted
Go string literal, returning the string value that s quotes. (If s is
single-quoted, it would be a Go character literal; Unquote returns the
corresponding one-character string.)

If there is an error then err != nil.

Peter
Post by Lambda
Some functions that return string will return empty string when
something is wrong.
len(str) == 0 or
str == ""
...
Which one is preferred?
--
To unsubscribe, reply using "remove me" as the subject.
Russ Cox
2010-04-08 18:50:44 UTC
Permalink
Post by Lambda
Some functions that return string will return empty string when
something is wrong.
len(str) == 0 or
str == ""
...
Which one is preferred?
The one that makes the code clear.
If I'm about to look at element x I typically write
len(s) > x, even for x == 0, but if I care about
"is it this specific string" I tend to write s == "".

It's reasonable to assume that a mature compiler will compile
len(s) == 0 and s == "" into the same, efficient code.
Right now 6g etc do compile s == "" into a function call
while len(s) == 0 is not, but that's been on my to-do list to fix.

Make the code clear.

Russ
--
To unsubscribe, reply using "remove me" as the subject.
Tong Sun
2015-07-29 01:36:32 UTC
Permalink
Any updates/conclusion on this?

To check if a string is empty or not, better use
Post by Lambda
len(str) == 0 or
str == ""
?

Thanks
Post by Lambda
Post by Lambda
Some functions that return string will return empty string when
something is wrong.
len(str) == 0 or
str == ""
...
Which one is preferred?
The one that makes the code clear.
If I'm about to look at element x I typically write
len(s) > x, even for x == 0, but if I care about
"is it this specific string" I tend to write s == "".
It's reasonable to assume that a mature compiler will compile
len(s) == 0 and s == "" into the same, efficient code.
Right now 6g etc do compile s == "" into a function call
while len(s) == 0 is not, but that's been on my to-do list to fix.
Make the code clear.
Russ
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Caleb Spare
2015-07-29 01:38:43 UTC
Permalink
"Using whichever makes the code clear" still applies. FWIW I think
that 'str == ""' is more clear almost 100% of the time.

They compile to the same code these days, so it doesn't have
performance implications.

-Caleb
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Tong Sun
2015-07-29 01:42:22 UTC
Permalink
Thanks. So,

`str == ""` for test empty, and
`str != ""` for not empty, right?
Post by Caleb Spare
"Using whichever makes the code clear" still applies. FWIW I think
that 'str == ""' is more clear almost 100% of the time.
They compile to the same code these days, so it doesn't have
performance implications.
-Caleb
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Giulio Iotti
2015-07-29 16:05:57 UTC
Permalink
Post by Tong Sun
Thanks. So,
`str == ""` for test empty, and
`str != ""` for not empty, right?
Right. And in practice only the first one, as you will use early return ;)
--
Giulio Iotti
https://twitter.com/dullgiulio
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
'Paul Borman' via golang-nuts
2015-07-29 16:29:37 UTC
Permalink
I regularly encourage using s == "" rather than s == len(0), though both
are valid and are equivalent. Using s == "" makes it very clear you are
looking at a string and not at a slice (yes, yes, a string could be
considered an immutable slice of bytes). On slices you have to be clear
about s == nil vs s == len(0) as while a nil slice has a length of 0, not
all slices of length 0 are nil (unlike strings, where all strings of length
0 are "")
Post by Giulio Iotti
Post by Tong Sun
Thanks. So,
`str == ""` for test empty, and
`str != ""` for not empty, right?
Right. And in practice only the first one, as you will use early return ;)
--
Giulio Iotti
https://twitter.com/dullgiulio
--
You received this message because you are subscribed to the Google Groups
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
t***@gmail.com
2015-07-29 15:46:38 UTC
Permalink
I think comparing to an empty string is silly, just check its len. len(s)
makes it clear you are checking its length and not comparing its content.
Post by Lambda
Some functions that return string will return empty string when
something is wrong.
len(str) == 0 or
str == ""
...
Which one is preferred?
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Staven
2015-07-29 15:52:52 UTC
Permalink
Post by t***@gmail.com
I think comparing to an empty string is silly, just check its len. len(s)
makes it clear you are checking its length and not comparing its content.
I agree. Using len(s) == 0 also accounts for all other strings of length 0.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Dan Kortschak
2015-07-29 21:43:06 UTC
Permalink
?
Post by Staven
Using len(s) == 0 also accounts for all other strings of length 0.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Kiki Sugiaman
2015-07-29 23:08:15 UTC
Permalink
My take: flip a coin, move on. This is one of the choices which won't
determine the success/failure of the software you ship. It won't be a
performance bottleneck either if you choose wrong.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Loading...