Dec 24, 2024 05:08:01 fliter <imc...@gmail.com>:
--
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.
To view this discussion visit https://groups.google.com/d/msgid/golang-nuts/4f95be15-1a7d-4cb8-a19d-eb33a1736d68n%40googlegroups.com.
On Dec 28, 2024, at 2:41 PM, Amnon <amn...@gmail.com> wrote:There are big advantages in maps.Keys and maps.Values returning iterators.
It allows us to iterate very big maps without having to allocate vast amounts of memory.
--
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.
To view this discussion visit https://groups.google.com/d/msgid/golang-nuts/8064C03C-51B9-4046-A5C2-88380A978FEE%40newclarity.net.
Why don't I use the sequence versions more frequently? Because I try not to create huge in-memory maps and instead prefer to move logic that manipulates large amounts of data into a proper database.
Then you must REALLY hate that the Go team chose these names in the standard library:
# strings Package
- Builder.Write() vs Builder.WriteString()
- Builder.WriteByte() vs Builder.WriteRune()
- Reader.Read() vs Reader.ReadString()
- Reader.ReadByte() vs Reader.ReadRune()
# bytes Package
- Buffer.Write() vs Buffer.WriteString()
- Buffer.WriteByte() vs Buffer.WriteRune()
- Reader.Read() vs Reader.ReadString()
- Reader.ReadByte() vs Reader.ReadRune()
# strconv Package
- strconv.AppendBool()
- strconv.AppendFloat()
- strconv.AppendInt()
- strconv.AppendUint()
- strconv.FormatBool()
- strconv.FormatFloat()
- strconv.FormatInt()
- strconv.FormatUint()
- strconv.ParseBool()
- strconv.ParseFloat()
- strconv.ParseInt()
- strconv.ParseUint()
# slices Package
- slices.Sort() vs slices.SortFunc()
- slices.IsSorted() vs slices.IsSortedFunc()
- slices.BinarySearch() vs slices.BinarySearchFunc()
- slices.Contains() vs slices.ContainsFunc()
- slices.Index() vs slices.IndexFunc()
- slices.LastIndex() vs slices.LastIndexFunc()
# maps Package
- maps.Equal() vs maps.EqualFunc()
# bufio Package
- Reader.Read() vs Reader.ReadString()
- Reader.ReadByte() vs Reader.ReadRune()
- Writer.Write() vs Writer.WriteString()
- Writer.WriteByte() vs Writer.WriteRune()
# archive/tar Package
- Reader.Read() vs Reader.ReadString()
- Writer.Write() vs Writer.WriteString()
-Mike
--
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.
To view this discussion visit https://groups.google.com/d/msgid/golang-nuts/28732884-0E56-4FAA-9DA4-C39700870CC7%40newclarity.net.
On Dec 29, 2024, at 5:11 PM, Axel Wagner <axel.wa...@googlemail.com> wrote:Why don't I use the sequence versions more frequently? Because I try not to create huge in-memory maps and instead prefer to move logic that manipulates large amounts of data into a proper database.Iterators are more efficient for small maps as well. Allocating and then throwing away small slices increases GC pressure. I got easily 10% or more performance improvements by refactoring a loop over a slice with a loop over an iterator.
All of these exist to implement different interface with different tradeoffs. For example, `WriteString` implements `io.StringWriter`, which is more efficient than calling `Write(string(p))`, because the latter would make the argument escape, thanks to the virtual call.Yes, it would be better to have simpler names. But given the nature of interfaces in Go, we need two different methods to do two different things and they need to have two different names. At least one of them, unfortunately, has to be bad.That doesn't disprove the principle, though.
Indeed. If we had more powerful generics (and had them from the beginning) we could have chosen singular functions with simpler names here. Perhaps, in the future, we *will* get those and can clean up here.
Why don't I use the sequence versions more frequently? Because I try not to create huge in-memory maps and instead prefer to move logic that manipulates large amounts of data into a proper database.Iterators are more efficient for small maps as well. Allocating and then throwing away small slices increases GC pressure. I got easily 10% or more performance improvements by refactoring a loop over a slice with a loop over an iterator.
On Monday, December 30, 2024 at 6:12:10 AM UTC+8 Axel Wagner wrote:Why don't I use the sequence versions more frequently? Because I try not to create huge in-memory maps and instead prefer to move logic that manipulates large amounts of data into a proper database.Iterators are more efficient for small maps as well. Allocating and then throwing away small slices increases GC pressure. I got easily 10% or more performance improvements by refactoring a loop over a slice with a loop over an iterator.This is typical micro benchmark. There are too such "allocating and then throwing away small slices" cases in Go programming.The iterator cases are just a tiny portion of them.
> Please note that "maps.Collect" is slow. https://github.com/golang/go/issues/68261Please note that I did address that in my message.CollectN matters most for non-trivial iterators, e.g. where you first transform an iterator using `xiter.Map` or the like.Something like slices.Collect(maps.Keys(m)) - which this discussion is about - can be relatively easily optimized by the compiler, if we want.
> This is typical micro benchmark. There are too such "allocating and then throwing away small slices" cases in Go programming. The iterator cases are just a tiny portion of them.I was talking about end-to-end execution time of the program. In a CPU-bound program, it is not uncommon for allocations in the inner loop to have significant effects.