Re: [go-nuts] Why does Go ignore HTTP_PROXY and HTTPS_PROXY if the proxy address is localhost

2021-04-14 Thread Orson Cart


On Wednesday, 14 April 2021 at 18:06:53 UTC+1 Adrian Ho wrote:

> The "Name Resolution" section in https://golang.org/pkg/net/ says:
>
> On Unix systems, the resolver has two options for resolving names. It can 
> use a pure Go resolver that sends DNS requests directly to the servers 
> listed in /etc/resolv.conf, or it can use a cgo-based resolver that calls C 
> library routines such as getaddrinfo and getnameinfo.
>
> By default the pure Go resolver is used, because a blocked DNS request 
> consumes only a goroutine, while a blocked C call consumes an operating 
> system thread.
>
> That might have some bearing on your problem. To see if it's the case, as 
> the page suggests:
>
> export GODEBUG=netdns=cgo   # force cgo resolver
>
>
> Best Regards,
> Adrian
>

Thanks Adrian. For the record, I'm working on Windows.

For the record I should also admit that I've been missing the blindingly 
obvious. At least it's blindingly obvious to me now.

I never occurred to me before that the client instance that I'm using has a 
non-default Transport. The way that the transport is initialised means that 
it has a nil Proxy - hence whatever I set in the environment didn't matter 
as it was being ignored.

This thread hasn't been my finest hour! 

Thanks to all for the help.

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/16791ca0-702a-4474-9052-76ce67ba9a42n%40googlegroups.com.


Re: [go-nuts] Why does Go ignore HTTP_PROXY and HTTPS_PROXY if the proxy address is localhost

2021-04-13 Thread Orson Cart
So, to clarify: 

1/ I have a proxy (Fiddler) running locally on port 
2/ my /etc/hosts file has an entry as follows: 127.0.0.1 fiddler
3/ My HTTP_PROXY and HTTPS_PROXY environment variables are set to 
http://fiddler: <http://localhost:/> and  https://fiddler: 
<http://localhost:/> respectively

if I then issue a request via curl then that request is picked up by the 
proxy.
However if I make the same request from my go application, the request 
appears to bypass the proxy and is sent directly. I'm perplexed.

Any advice would be appreciated.



On Tuesday, 13 April 2021 at 22:26:06 UTC+1 Orson Cart wrote:

> Thanks for the reply. 
>
> Yes I did add an alias to the /etc/hosts file and it makes no difference. 
> The requests still bypass the proxy.
>
> As you point out it's possible to achieve the goal in code but I'd really 
> like to do it without changing the code if at all possible.
>
> I'm also just really curious now as to why the go libraries aren't 
> honouring the environment variables.
>
> Thanks for the input.
>
> On Tuesday, 13 April 2021 at 21:36:48 UTC+1 wagner riffel wrote:
>
>> On Tue Apr 13, 2021 at 7:07 PM UTC, Orson Cart wrote:
>> > I'm perplexed :(
>> >
>>
>> Did you tried the /etc/hosts? I think that would do it, if not,
>> something like this may do the trick:
>>
>> if debug {
>> t := http.DefaultTransport.(*http.Transport)
>> t.Proxy = func(r *http.Request) (*url.URL, error) {
>> return url.Parse("http://localhost:;)
>> }
>> }
>>
>> note: i did not tested, just shooting.
>>
>> --wagner
>>
>

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/708a6171-66bc-42bc-9284-0d46c7942d9dn%40googlegroups.com.


Re: [go-nuts] Why does Go ignore HTTP_PROXY and HTTPS_PROXY if the proxy address is localhost

2021-04-13 Thread Orson Cart
So, to clarify: With my HTTP_PROXY and HTTPS_PROXY environment variables 
set to http://localhost: and  https://localhost:  respectively, if 
I issue a request via curl then that request is picked up by the proxy.
However if I make the same request from my go application, the request 
appears to bypass the proxy and is sent directly.

Any advice would be appreciated.

On Tuesday, 13 April 2021 at 22:26:06 UTC+1 Orson Cart wrote:

> Thanks for the reply. 
>
> Yes I did add an alias to the /etc/hosts file and it makes no difference. 
> The requests still bypass the proxy.
>
> As you point out it's possible to achieve the goal in code but I'd really 
> like to do it without changing the code if at all possible.
>
> I'm also just really curious now as to why the go libraries aren't 
> honouring the environment variables.
>
> Thanks for the input.
>
> On Tuesday, 13 April 2021 at 21:36:48 UTC+1 wagner riffel wrote:
>
>> On Tue Apr 13, 2021 at 7:07 PM UTC, Orson Cart wrote:
>> > I'm perplexed :(
>> >
>>
>> Did you tried the /etc/hosts? I think that would do it, if not,
>> something like this may do the trick:
>>
>> if debug {
>> t := http.DefaultTransport.(*http.Transport)
>> t.Proxy = func(r *http.Request) (*url.URL, error) {
>> return url.Parse("http://localhost:;)
>> }
>> }
>>
>> note: i did not tested, just shooting.
>>
>> --wagner
>>
>

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/d6bd8344-59bb-4cd4-a9c5-3c1986d93724n%40googlegroups.com.


Re: [go-nuts] Why does Go ignore HTTP_PROXY and HTTPS_PROXY if the proxy address is localhost

2021-04-13 Thread Orson Cart
Thanks for the reply. 

Yes I did add an alias to the /etc/hosts file and it makes no difference. 
The requests still bypass the proxy.

As you point out it's possible to achieve the goal in code but I'd really 
like to do it without changing the code if at all possible.

I'm also just really curious now as to why the go libraries aren't 
honouring the environment variables.

Thanks for the input.

On Tuesday, 13 April 2021 at 21:36:48 UTC+1 wagner riffel wrote:

> On Tue Apr 13, 2021 at 7:07 PM UTC, Orson Cart wrote:
> > I'm perplexed :(
> >
>
> Did you tried the /etc/hosts? I think that would do it, if not,
> something like this may do the trick:
>
> if debug {
> t := http.DefaultTransport.(*http.Transport)
> t.Proxy = func(r *http.Request) (*url.URL, error) {
> return url.Parse("http://localhost:;)
> }
> }
>
> note: i did not tested, just shooting.
>
> --wagner
>

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/91dd7a03-4455-4fd6-854c-a588bd439925n%40googlegroups.com.


Re: [go-nuts] Why does Go ignore HTTP_PROXY and HTTPS_PROXY if the proxy address is localhost

2021-04-13 Thread Orson Cart
Please accept my ay apologies. I'd misunderstood the documentation.

I was looking for a reason why my go application's requests aren't being 
sent to the proxy that I've specified using HTTP_PROXY and HTTPS_PROXY. 
When I saw the comment in the documentation I thought I'd found an 
explanation even if I didn't understand the reason for it being that way.

So now I'm left with my original problem: I have HTTP_PROXY set to 
http://localhost: and HTTPS_PROXY set to https://localhost:. I also 
have a proxy (Fiddler) running on localhost: but requests from my 
application appear to go direct, bypassing the proxy.

I'm perplexed :(

On Tuesday, 13 April 2021 at 19:17:10 UTC+1 wagner riffel wrote:

> On Tue Apr 13, 2021 at 2:14 PM -03, Orson Cart wrote:
> > Can anyone explain the reasoning behind this? It rather interferes with
> > debugging traffic using a local proxy like Fiddler.
> >
>
> My guess here it's for preventing the remote from tricking the proxy to
> make request to internal services that couldn't be reached otherwise.
>
> > I've seen suggestions to define an alternative hostname in /etc/hosts
> > but as far as I can tell this doesn't work either.
> >
>
> The code you linked doesn't seen to try that hard to block loopback
> requests, I do think that an /etc/hosts entry to 127.0.0.1 should
> bypass the proxy, if not I don't see any other way around other than
> implementing the RoundTripper yourself, which shouldn't be hard for
> such simple use.
>
> --wagner
>

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/ac6c1bae-2153-41b3-9037-110fc0eb12cfn%40googlegroups.com.


[go-nuts] Why does Go ignore HTTP_PROXY and HTTPS_PROXY if the proxy address is localhost

2021-04-13 Thread Orson Cart
>From the documentation for ProxyFromEnvironment 
:
"As a special case, if req.URL.Host is "localhost" (with or without a port 
number), then a nil URL and nil error will be returned."

Can anyone explain the reasoning behind this? It rather interferes with 
debugging traffic using a local proxy like Fiddler.

I've seen suggestions to define an alternative hostname in /etc/hosts but 
as far as I can tell this doesn't work either.

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/499a922f-2298-4cef-ba3d-c16e38e6e548n%40googlegroups.com.


[go-nuts] Why is go ignoring my HTTP_PROXY environment variable

2021-04-13 Thread Orson Cart
I am trying to use Fiddler to debug some issues in a go application. To do 
this I need to make the application use Fiddler's proxy endpoint 
(127.0.0.1:).

I can do this in code but I'd rather not as it would mean updating the code 
just for the purpose of this debugging session.

As I understand it, go will use the HTTP_PROXY environment variable if it's 
set so I have set it as follows:
export HTTP_PROXY=https://127.0.0.1:

However I am seeing nothing in Fiddler.

I read somewhere that go purposely ignores proxies set to 127.0.0.1, 
localhost or anything that evaluates to localhost. Can anyone confirm this 
and if possible explain why this is?

Thanks
 

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/c5b782a8-9c6f-49ad-944e-cdfba0b58b97n%40googlegroups.com.


Re: [go-nuts] Re: Question about "go get", modules and indirect dependencies

2021-01-06 Thread Orson Cart
Thanks for the suggestions and the issue link. That did the trick:
go list -m all

Thanks for your help.

On Wednesday, 6 January 2021 at 18:39:03 UTC Bryan C. Mills wrote:

> Yeah, that's exactly https://golang.org/issue/42723. `go list` shouldn't 
> need to read those files.
>
> In the meantime, you could try `go list all` and/or `go mod tidy` after 
> your `go get`..?
>
>
> On Wed, Jan 6, 2021 at 1:27 PM Orson Cart  wrote:
>
>> Thanks for the advice Bryan.
>>
>> Sadly I tried using go mod download but I'm still seeing the same 
>> problem. I'm concerned that it might be something environmental.
>>
>> The module that's been causing me the issue is  
>> github.com/jung-kurt/gofpdf v1.16.2
>>
>> I tried again but this time with a different module:
>> go mod download go.elastic.co/a...@v1.8.0 
>> <http://go.elastic.co/apm@v1.8.0>
>> This populated the cache with a couple of dozen modules but the only info 
>> file that gets downloaded is go/pkg/mod/cache/download/go 
>> <https://goto.google.com/pkg/mod/cache/download/go>.
>> elastic.co/apm/@v/v1.16.2.info
>>
>> Then on a whim I cleaned the cache again and ran "go get" on this new 
>> module:
>> go get go.elastic.co/a...@v1.8.0 <http://go.elastic.co/apm@v1.8.0>
>> go: downloading go.elastic.co/apm v1.8.0
>> go: downloading go.elastic.co/fastjson v1.0.0
>> go: downloading github.com/santhosh-tekuri/jsonschema v1.2.4
>> go: downloading github.com/pkg/errors v0.8.1
>> go: downloading golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e
>> go: downloading github.com/elastic/go-sysinfo v1.1.1
>> go: downloading github.com/armon/go-radix v1.0.0
>> go: downloading github.com/elastic/go-windows v1.0.0
>> go: downloading github.com/prometheus/procfs v0.0.3
>> go: downloading github.com/joeshaw/multierror 
>> v0.0.0-20140124173710-69b34d4ec901
>> go: downloading howett.net/plist v0.0.0-20181124034731-591f970eefbb
>>
>> This time all but two of the downloaded modules contained .info files.
>>
>> I don't get it.
>>
>> One thing that I did note was that when I go back to using "go get" on 
>> the original module, it  caches a number of modules into the but it only 
>> *reports* one:
>> go get github.com/jung-kurt/gof...@v1.16.2 
>> <http://github.com/jung-kurt/gofpdf@v1.16.2>
>> go: downloading github.com/jung-kurt/gofpdf v1.16.2
>> The only .info file that's downloaded is  go\pkg\mod\cache\download\
>> github.com\jung-kurt\gofpdf\@v\v1.16.2.info
>> I'm wondering if that's hinting at something?
>>
>> I'm not interested in the info files per se. It's just that we're using 
>> our own module proxy and some of our developers are using GoLand. When 
>> GoLand opens a project it seems to run "go list" on all dependencies and 
>> reports an http 404 on any .info files that it can't download. Because some 
>> of our dependencies don't have .info files, we get the http 404s. 
>> Aside from that the lack of info files doesn't seem to stop us from using 
>> GoLand but all the same I'd rather we fixed the errors.
>>
>> On Wednesday, 6 January 2021 at 16:21:25 UTC Bryan C. Mills wrote:
>>
>>> `go mod download` should include `.info` files for the requested 
>>> module(s), or for all dependencies of your module (if you don't give any 
>>> specific modules as arguments).
>>>
>>> That said, .info files are not particularly useful in general, and the 
>>> `go` command should probably read them less than in does today; see 
>>> https://golang.org/issue/42723 for details;
>>>
>>> On Tuesday, January 5, 2021 at 2:10:05 PM UTC-5 Orson Cart wrote:
>>>
>>>> Apologies if this is a dumb question as I don't have a great deal of 
>>>> experience with modules.
>>>>
>>>> So, if I use the "go get" command to download a module, when I look in 
>>>> the module cache the @v directory of the requested module contains at 
>>>> least 
>>>> one .info file.
>>>> This isn't the case for any indirect dependencies which seem to contain 
>>>> only list, list.lock and .mod files.
>>>>
>>>> There must be a way to have all of the .info files downloaded to the 
>>>> cache because the goland ide does this when it opens a module directlry 
>>>> and 
>>>> the cache is empty. I just don't know what command it's using to achieve 
>>>> it.
>>>>
>>>&

[go-nuts] Re: Question about "go get", modules and indirect dependencies

2021-01-06 Thread Orson Cart
Thanks for the advice Bryan.

Sadly I tried using go mod download but I'm still seeing the same problem. 
I'm concerned that it might be something environmental.

The module that's been causing me the issue is  github.com/jung-kurt/gofpdf 
v1.16.2

I tried again but this time with a different module:
go mod download go.elastic.co/apm@v1.8.0
This populated the cache with a couple of dozen modules but the only info 
file that gets downloaded is 
go/pkg/mod/cache/download/go.elastic.co/apm/@v/v1.16.2.info

Then on a whim I cleaned the cache again and ran "go get" on this new 
module:
go get go.elastic.co/apm@v1.8.0
go: downloading go.elastic.co/apm v1.8.0
go: downloading go.elastic.co/fastjson v1.0.0
go: downloading github.com/santhosh-tekuri/jsonschema v1.2.4
go: downloading github.com/pkg/errors v0.8.1
go: downloading golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e
go: downloading github.com/elastic/go-sysinfo v1.1.1
go: downloading github.com/armon/go-radix v1.0.0
go: downloading github.com/elastic/go-windows v1.0.0
go: downloading github.com/prometheus/procfs v0.0.3
go: downloading github.com/joeshaw/multierror 
v0.0.0-20140124173710-69b34d4ec901
go: downloading howett.net/plist v0.0.0-20181124034731-591f970eefbb

This time all but two of the downloaded modules contained .info files.

I don't get it.

One thing that I did note was that when I go back to using "go get" on the 
original module, it  caches a number of modules into the but it only 
*reports* one:
go get github.com/jung-kurt/gofpdf@v1.16.2
go: downloading github.com/jung-kurt/gofpdf v1.16.2
The only .info file that's downloaded is  
go\pkg\mod\cache\download\github.com\jung-kurt\gofpdf\@v\v1.16.2.info
I'm wondering if that's hinting at something?

I'm not interested in the info files per se. It's just that we're using our 
own module proxy and some of our developers are using GoLand. When GoLand 
opens a project it seems to run "go list" on all dependencies and reports 
an http 404 on any .info files that it can't download. Because some of our 
dependencies don't have .info files, we get the http 404s. 
Aside from that the lack of info files doesn't seem to stop us from using 
GoLand but all the same I'd rather we fixed the errors.

On Wednesday, 6 January 2021 at 16:21:25 UTC Bryan C. Mills wrote:

> `go mod download` should include `.info` files for the requested 
> module(s), or for all dependencies of your module (if you don't give any 
> specific modules as arguments).
>
> That said, .info files are not particularly useful in general, and the 
> `go` command should probably read them less than in does today; see 
> https://golang.org/issue/42723 for details;
>
> On Tuesday, January 5, 2021 at 2:10:05 PM UTC-5 Orson Cart wrote:
>
>> Apologies if this is a dumb question as I don't have a great deal of 
>> experience with modules.
>>
>> So, if I use the "go get" command to download a module, when I look in 
>> the module cache the @v directory of the requested module contains at least 
>> one .info file.
>> This isn't the case for any indirect dependencies which seem to contain 
>> only list, list.lock and .mod files.
>>
>> There must be a way to have all of the .info files downloaded to the 
>> cache because the goland ide does this when it opens a module directlry and 
>> the cache is empty. I just don't know what command it's using to achieve it.
>>
>> So, does anyone know a command which will download all dependencies 
>> complete with their .info files?
>>
>> Thanks
>>
>

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/edb36cbc-e814-4712-9582-c0e9633597b9n%40googlegroups.com.


[go-nuts] Question about "go get", modules and indirect dependencies

2021-01-05 Thread Orson Cart
Apologies if this is a dumb question as I don't have a great deal of 
experience with modules.

So, if I use the "go get" command to download a module, when I look in the 
module cache the @v directory of the requested module contains at least one 
.info file.
This isn't the case for any indirect dependencies which seem to contain 
only list, list.lock and .mod files.

There must be a way to have all of the .info files downloaded to the cache 
because the goland ide does this when it opens a module directlry and the 
cache is empty. I just don't know what command it's using to achieve it.

So, does anyone know a command which will download all dependencies 
complete with their .info files?

Thanks

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/3ab4ed86-9be5-42db-b9f9-67547deab6f4n%40googlegroups.com.


Re: [go-nuts] Re: Bencharking issue with b.StartTimer and b.StopTimer. Was: Benchmark using b.StopTimer and b.StartTimer has unexpected behaviour - to me at least

2020-03-24 Thread Orson Cart
On Tuesday, 24 March 2020 21:00:38 UTC, Sean Liao wrote:
>
> setup upfront shouldn't be a problem
> b.N is constant throughout the function lifetime, the entire function is 
> called multiple times during benchmarking
>

Thank you! I'd missed that. That makes things so much more straightforward 
for me.

 

>
> On Tuesday, March 24, 2020 at 9:56:19 PM UTC+1, Orson Cart wrote:
>>
>> On Tuesday, 24 March 2020 20:47:07 UTC, Robert Engels wrote:
>>>
>>> One way to handle this is to generate all of the data up front in an 
>>> array and then just index into the array based on the run. 
>>>
>>
>> Yeah, I had thought of that before posting but then I'd have to decide on 
>> a value for b.N. I was trying to roll with the idea of the framework 
>> establishing a value. To be honest if it wasn't for the fact that I was 
>> just curious as to why it wasn't working I'd just have settled for an array 
>> with a fixed b.N.
>>
>> All part of my golang learning experience
>>
>>  
>>
>>>
>>> On Mar 24, 2020, at 3:42 PM, Orson Cart  wrote:
>>>
>>> 
>>>
>>>
>>> On Tuesday, 24 March 2020 20:27:39 UTC, Adrian Ratnapala wrote:
>>>>
>>>> ...
>>>
>>> So that sounds like the use-case is to call Stop-, StartTimer once 
>>>> before you enter the main loop of the benchmark.  They not efficient 
>>>> enough for a tight inner loop. 
>>>>
>>>
>>> Thanks for the input and I think that you are probably correct. It would 
>>> be nice if the docs said that though.
>>>
>>> The code that I'm profiling wasn't written by me. It's fast but it 
>>> modifies its input data so it needs new data on each iteration. The 
>>> implementation is non-trivial and it might be a maintenance headache. I've 
>>> been asked to benchmark it along with less complicated implementations. It 
>>> was whilst trying to set up per-iteration test data that I came across this 
>>> issue.
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>  
>>>
>>>>
>>>> On Wed, 25 Mar 2020 at 06:51, Jake Montgomery  
>>>> wrote: 
>>>> > 
>>>> > Strange. I hope someone has a real answer for you. 
>>>> > 
>>>> > In the meantime, you can simplify your example to demonstrate the 
>>>> issue: 
>>>> > 
>>>> > package demo_test 
>>>> > 
>>>> > import ( 
>>>> > "testing" 
>>>> > ) 
>>>> > 
>>>> > var Foo1 []string 
>>>> > var Count int = 8 
>>>> > 
>>>> > func Benchmark1(b *testing.B) { 
>>>> > for i := 0; i < b.N; i++ { 
>>>> > Foo1 = foo(Count) 
>>>> > } 
>>>> > } 
>>>> > 
>>>> > func Benchmark2(b *testing.B) { 
>>>> > b.StopTimer() 
>>>> > for i := 0; i < b.N; i++ { 
>>>> > // Hypothetical setup here 
>>>> > b.StartTimer() 
>>>> > Foo1 = foo(Count) 
>>>> > b.StopTimer() 
>>>> > } 
>>>> > } 
>>>> > 
>>>> > 
>>>> > func foo(count int) []string { 
>>>> > testData := []string{} 
>>>> > for i := 0; i < count; i++ { 
>>>> > testData = append(testData, "a") 
>>>> > } 
>>>> > 
>>>> > return testData 
>>>> > } 
>>>> > 
>>>> > I get: 
>>>> > 
>>>> > goos: windows 
>>>> > goarch: amd64 
>>>> > Benchmark1-4 2101567   584 ns/op 
>>>> > Benchmark2-4 100  1668 ns/op 
>>>> > PASS 
>>>> > 
>>>> > So it appears that StopTimer() and StartTimer() are introducing some 
>>>> overhead. I am surprised that it is this large. 
>>>> > 
>>>> > Good Luck 
>>>> > 
>>>> > 
>>>> > 
>>>> > On Tuesday, March 24, 2020 at 12:24:08 PM UTC-4, Orson Cart wrote: 
>>>> >> 
>>>> >> I posted this earlier but I realised that the code had a fundamental 
>>>> error in it. I've corrected here it but the underlying problem still 
>>>> exist

Re: [go-nuts] Re: Bencharking issue with b.StartTimer and b.StopTimer. Was: Benchmark using b.StopTimer and b.StartTimer has unexpected behaviour - to me at least

2020-03-24 Thread Orson Cart
On Tuesday, 24 March 2020 20:47:07 UTC, Robert Engels wrote:
>
> One way to handle this is to generate all of the data up front in an array 
> and then just index into the array based on the run. 
>

Yeah, I had thought of that before posting but then I'd have to decide on a 
value for b.N. I was trying to roll with the idea of the framework 
establishing a value. To be honest if it wasn't for the fact that I was 
just curious as to why it wasn't working I'd just have settled for an array 
with a fixed b.N.

All part of my golang learning experience

 

>
> On Mar 24, 2020, at 3:42 PM, Orson Cart  > wrote:
>
> 
>
>
> On Tuesday, 24 March 2020 20:27:39 UTC, Adrian Ratnapala wrote:
>>
>> ...
>
> So that sounds like the use-case is to call Stop-, StartTimer once 
>> before you enter the main loop of the benchmark.  They not efficient 
>> enough for a tight inner loop. 
>>
>
> Thanks for the input and I think that you are probably correct. It would 
> be nice if the docs said that though.
>
> The code that I'm profiling wasn't written by me. It's fast but it 
> modifies its input data so it needs new data on each iteration. The 
> implementation is non-trivial and it might be a maintenance headache. I've 
> been asked to benchmark it along with less complicated implementations. It 
> was whilst trying to set up per-iteration test data that I came across this 
> issue.
>
>
>
>
>
>
>
>  
>
>>
>> On Wed, 25 Mar 2020 at 06:51, Jake Montgomery  wrote: 
>> > 
>> > Strange. I hope someone has a real answer for you. 
>> > 
>> > In the meantime, you can simplify your example to demonstrate the 
>> issue: 
>> > 
>> > package demo_test 
>> > 
>> > import ( 
>> > "testing" 
>> > ) 
>> > 
>> > var Foo1 []string 
>> > var Count int = 8 
>> > 
>> > func Benchmark1(b *testing.B) { 
>> > for i := 0; i < b.N; i++ { 
>> > Foo1 = foo(Count) 
>> > } 
>> > } 
>> > 
>> > func Benchmark2(b *testing.B) { 
>> > b.StopTimer() 
>> > for i := 0; i < b.N; i++ { 
>> > // Hypothetical setup here 
>> > b.StartTimer() 
>> > Foo1 = foo(Count) 
>> > b.StopTimer() 
>> > } 
>> > } 
>> > 
>> > 
>> > func foo(count int) []string { 
>> > testData := []string{} 
>> > for i := 0; i < count; i++ { 
>> > testData = append(testData, "a") 
>> > } 
>> > 
>> > return testData 
>> > } 
>> > 
>> > I get: 
>> > 
>> > goos: windows 
>> > goarch: amd64 
>> > Benchmark1-4 2101567   584 ns/op 
>> > Benchmark2-4 100  1668 ns/op 
>> > PASS 
>> > 
>> > So it appears that StopTimer() and StartTimer() are introducing some 
>> overhead. I am surprised that it is this large. 
>> > 
>> > Good Luck 
>> > 
>> > 
>> > 
>> > On Tuesday, March 24, 2020 at 12:24:08 PM UTC-4, Orson Cart wrote: 
>> >> 
>> >> I posted this earlier but I realised that the code had a fundamental 
>> error in it. I've corrected here it but the underlying problem still 
>> exists. 
>> >> 
>> >> I've recently started using go test's benchmarks support and I'm 
>> particularly interested in understanding the benchmark timer functions. 
>> I've been getting results that I found surprising and I was wondering if 
>> anyone could explain what's going on here. 
>> >> 
>> >> The code below has three benchmarks that each invoke a single function 
>> (foo). The implementation of foo isn't important, it's just there to 
>> consume some time: 
>> >> - foo is called once per iteration in Benchmark1. 
>> >> - It's called twice per iteration in Benchmark2 so I'd expect 
>> Benchmark2's duration to be nominally twice that of Benchmark1. 
>> >> - It's also called twice per iteration in Benchmark3 but the first 
>> call is wrapped in b.StopTimer and b.startTimer calls. Because of this I'd 
>> have expected Benchmark3 to be about the same duration as Benchmark1 
>> >> 
>> >> Apologies for the length of the example but I didn't think it fair to 
>> ask the question and leave anything out. 
>> >> 
>> >> package demo_test 
>> >> 
>> >> import ( 
>> >> "strconv" 
>&

[go-nuts] Re: Bencharking issue with b.StartTimer and b.StopTimer. Was: Benchmark using b.StopTimer and b.StartTimer has unexpected behaviour - to me at least

2020-03-24 Thread Orson Cart
On Tuesday, 24 March 2020 20:16:21 UTC, Jake Montgomery wrote:
>
> I took a quick glance at the code, and I think I figured it out. The 
> benchmark code, including StartTimer() and StopTimer() use time.Now(). On 
> my windows  machine time.Now() has an accuracy of 1ms. So by calling it for 
> every iteration, when the actual time is 600ns just makes the whole thing 
> wildly inaccurate. That 1ms accuracy is ok when the benchmark calls it once 
> then runs the code 2 million times. But when called each time the accuracy 
> of the time.Now() code becomes dominant. 
>
> It is just an educated guess, but that is what it looks like to me.
>

Thanks once again. Others on the thread have pointed out more potential 
issues. I feel a bit like a carpenter who has to measure a piece of wood 
but who only has a rubber rule :D

 

>
>
> Perhaps there should be some sort of warning in the docs? 
>
>
>
> On Tuesday, March 24, 2020 at 4:01:17 PM UTC-4, Orson Cart wrote:
>>
>> On Tuesday, 24 March 2020 19:51:24 UTC, Jake Montgomery wrote:
>>>
>>> Strange. I hope someone has a real answer for you.
>>>
>>> In the meantime, you can simplify your example to demonstrate the issue:
>>>
>>
>> Thanks for taking a look at the code Jake. Just one question: you have 
>> the call to b.StopTimer outside of the loop and the call to b.StartTimer 
>> inside. Was that intentional?
>>
>> I'd have thought that the call to b.StartTimer would be a no-op after the 
>> first iteration.
>>
>>
>>
>>
>>
>>
>>  
>>
>>>
>>> package demo_test
>>>
>>> import (
>>> "testing"
>>> )
>>>
>>> var Foo1 []string
>>> var Count int = 8
>>>
>>> func Benchmark1(b *testing.B) {
>>> for i := 0; i < b.N; i++ {
>>> Foo1 = foo(Count)
>>> }
>>> }
>>>
>>> func Benchmark2(b *testing.B) {
>>> b.StopTimer()
>>> for i := 0; i < b.N; i++ {
>>> // Hypothetical setup here 
>>> b.StartTimer()
>>> Foo1 = foo(Count)
>>> b.StopTimer()
>>> }
>>> }
>>>
>>>
>>> func foo(count int) []string {
>>> testData := []string{}
>>> for i := 0; i < count; i++ {
>>> testData = append(testData, "a")
>>> }
>>>
>>> return testData
>>> }
>>>
>>> I get:
>>>
>>> goos: windows
>>> goarch: amd64
>>> Benchmark1-4 2101567   584 ns/op
>>> Benchmark2-4 100  1668 ns/op
>>> PASS
>>>
>>> So it appears that StopTimer() and StartTimer() are introducing some 
>>> overhead. I am surprised that it is this large.
>>>
>>> Good Luck
>>>
>>>
>>>
>>> On Tuesday, March 24, 2020 at 12:24:08 PM UTC-4, Orson Cart wrote:
>>>>
>>>> I posted this earlier but I realised that the code had a fundamental 
>>>> error in it. I've corrected here it but the underlying problem still 
>>>> exists.
>>>>
>>>> I've recently started using go test's benchmarks support and I'm 
>>>> particularly interested in understanding the benchmark timer functions. 
>>>> I've been getting results that I found surprising and I was wondering if 
>>>> anyone could explain what's going on here.
>>>>
>>>> The code below has three benchmarks that each invoke a single function 
>>>> (foo). The implementation of foo isn't important, it's just there to 
>>>> consume some time:
>>>> - foo is called once per iteration in Benchmark1.
>>>> - It's called twice per iteration in Benchmark2 so I'd expect 
>>>> Benchmark2's duration to be nominally twice that of Benchmark1.
>>>> - It's also called twice per iteration in Benchmark3 but the first call 
>>>> is wrapped in b.StopTimer and b.startTimer calls. Because of this I'd have 
>>>> expected Benchmark3 to be about the same duration as Benchmark1
>>>>
>>>> Apologies for the length of the example but I didn't think it fair to 
>>>> ask the question and leave anything out.
>>>>
>>>> package demo_test
>>>>
>>>> import (
>>>> "strconv"
>>>> "testing"
>>>> )
>>>>
>>>> var Foo1 []string
>>>> var Foo2 []string

Re: [go-nuts] Re: Bencharking issue with b.StartTimer and b.StopTimer. Was: Benchmark using b.StopTimer and b.StartTimer has unexpected behaviour - to me at least

2020-03-24 Thread Orson Cart


On Tuesday, 24 March 2020 20:27:39 UTC, Adrian Ratnapala wrote:
>
> ...

So that sounds like the use-case is to call Stop-, StartTimer once 
> before you enter the main loop of the benchmark.  They not efficient 
> enough for a tight inner loop. 
>

Thanks for the input and I think that you are probably correct. It would be 
nice if the docs said that though.

The code that I'm profiling wasn't written by me. It's fast but it modifies 
its input data so it needs new data on each iteration. The implementation 
is non-trivial and it might be a maintenance headache. I've been asked to 
benchmark it along with less complicated implementations. It was whilst 
trying to set up per-iteration test data that I came across this issue.







 

>
> On Wed, 25 Mar 2020 at 06:51, Jake Montgomery  > wrote: 
> > 
> > Strange. I hope someone has a real answer for you. 
> > 
> > In the meantime, you can simplify your example to demonstrate the issue: 
> > 
> > package demo_test 
> > 
> > import ( 
> > "testing" 
> > ) 
> > 
> > var Foo1 []string 
> > var Count int = 8 
> > 
> > func Benchmark1(b *testing.B) { 
> > for i := 0; i < b.N; i++ { 
> > Foo1 = foo(Count) 
> > } 
> > } 
> > 
> > func Benchmark2(b *testing.B) { 
> > b.StopTimer() 
> > for i := 0; i < b.N; i++ { 
> > // Hypothetical setup here 
> > b.StartTimer() 
> > Foo1 = foo(Count) 
> > b.StopTimer() 
> > } 
> > } 
> > 
> > 
> > func foo(count int) []string { 
> > testData := []string{} 
> > for i := 0; i < count; i++ { 
> > testData = append(testData, "a") 
> > } 
> > 
> > return testData 
> > } 
> > 
> > I get: 
> > 
> > goos: windows 
> > goarch: amd64 
> > Benchmark1-4     2101567   584 ns/op 
> > Benchmark2-4 100  1668 ns/op 
> > PASS 
> > 
> > So it appears that StopTimer() and StartTimer() are introducing some 
> overhead. I am surprised that it is this large. 
> > 
> > Good Luck 
> > 
> > 
> > 
> > On Tuesday, March 24, 2020 at 12:24:08 PM UTC-4, Orson Cart wrote: 
> >> 
> >> I posted this earlier but I realised that the code had a fundamental 
> error in it. I've corrected here it but the underlying problem still 
> exists. 
> >> 
> >> I've recently started using go test's benchmarks support and I'm 
> particularly interested in understanding the benchmark timer functions. 
> I've been getting results that I found surprising and I was wondering if 
> anyone could explain what's going on here. 
> >> 
> >> The code below has three benchmarks that each invoke a single function 
> (foo). The implementation of foo isn't important, it's just there to 
> consume some time: 
> >> - foo is called once per iteration in Benchmark1. 
> >> - It's called twice per iteration in Benchmark2 so I'd expect 
> Benchmark2's duration to be nominally twice that of Benchmark1. 
> >> - It's also called twice per iteration in Benchmark3 but the first call 
> is wrapped in b.StopTimer and b.startTimer calls. Because of this I'd have 
> expected Benchmark3 to be about the same duration as Benchmark1 
> >> 
> >> Apologies for the length of the example but I didn't think it fair to 
> ask the question and leave anything out. 
> >> 
> >> package demo_test 
> >> 
> >> import ( 
> >> "strconv" 
> >> "testing" 
> >> ) 
> >> 
> >> var Foo1 []string 
> >> var Foo2 []string 
> >> var Count int = 32767 
> >> 
> >> func Benchmark1(b *testing.B) { 
> >> for i := 0; i < b.N; i++{ 
> >> Foo1 = foo(Count) 
> >> } 
> >> } 
> >> 
> >> func Benchmark2(b *testing.B) { 
> >> for i := 0; i < b.N; i++{ 
> >> Foo1 = foo(Count) 
> >> Foo2 = foo(Count) 
> >> } 
> >> } 
> >> 
> >> func Benchmark3(b *testing.B) { 
> >> for i := 0; i < b.N; i++{ 
> >> b.StopTimer() 
> >> Foo1 = foo(Count) 
> >> b.StartTimer() 
> >> Foo2 = foo(Count) 
> >> } 
> >> } 
> >> 
> >> func foo(count int) []string{ 
> >> testData := []string{} 
> >> for i:= 0; i < count; i++ { 
> >> testData = append(testData, strconv.Itoa(i)) 
> >> } 
> >> 
> >> return testData 
> >> } 
> >> 
> >> 
&

[go-nuts] Re: Bencharking issue with b.StartTimer and b.StopTimer. Was: Benchmark using b.StopTimer and b.StartTimer has unexpected behaviour - to me at least

2020-03-24 Thread Orson Cart


On Tuesday, 24 March 2020 20:26:10 UTC, Sean Liao wrote:
>
> see https://github.com/golang/go/issues/27217
>

Thanks, will do.


 

>
>
> On Tuesday, March 24, 2020 at 5:24:08 PM UTC+1, Orson Cart wrote:
>>
>> I posted this earlier but I realised that the code had a fundamental 
>> error in it. I've corrected here it but the underlying problem still exists.
>>
>> I've recently started using go test's benchmarks support and I'm 
>> particularly interested in understanding the benchmark timer functions. 
>> I've been getting results that I found surprising and I was wondering if 
>> anyone could explain what's going on here.
>>
>> The code below has three benchmarks that each invoke a single function 
>> (foo). The implementation of foo isn't important, it's just there to 
>> consume some time:
>> - foo is called once per iteration in Benchmark1.
>> - It's called twice per iteration in Benchmark2 so I'd expect 
>> Benchmark2's duration to be nominally twice that of Benchmark1.
>> - It's also called twice per iteration in Benchmark3 but the first call 
>> is wrapped in b.StopTimer and b.startTimer calls. Because of this I'd have 
>> expected Benchmark3 to be about the same duration as Benchmark1
>>
>> Apologies for the length of the example but I didn't think it fair to ask 
>> the question and leave anything out.
>>
>> package demo_test
>>
>> import (
>> "strconv"
>> "testing"
>> )
>>
>> var Foo1 []string
>> var Foo2 []string
>> var Count int = 32767
>>
>> func Benchmark1(b *testing.B) {
>> for i := 0; i < b.N; i++{
>> Foo1 = foo(Count)
>> }
>> }
>>
>> func Benchmark2(b *testing.B) {
>> for i := 0; i < b.N; i++{
>> Foo1 = foo(Count)
>> Foo2 = foo(Count)
>> }
>> }
>>
>> func Benchmark3(b *testing.B) {
>> for i := 0; i < b.N; i++{
>> b.StopTimer()
>> Foo1 = foo(Count)
>> b.StartTimer()
>> Foo2 = foo(Count)
>> }
>> }
>>
>> func foo(count int) []string{
>> testData := []string{}
>> for i:= 0; i < count; i++ {
>> testData = append(testData, strconv.Itoa(i))
>> }
>>
>> return testData
>> }
>>
>>
>> When the benchmarks are run the results are as follows:
>>
>> Benchmark1-4 351   3345215 ns/op
>> Benchmark2-4 166   7206582 ns/op
>> Benchmark3-4 334   3457907 ns/op
>> PASS
>> ok  bar.com/benchmarks  6.881s
>>
>> OK benchmark3 is a little slower than Benchmark1 but that's not what's 
>> bothering me. It's this: if I now change Count to something much smaller 
>> the results are a surprise, at least to me. Here are the results when Count 
>> = 8:
>>
>> Benchmark1-4 2706196   442 ns/op
>> Benchmark2-4 1357482   873 ns/op
>> Benchmark3-4  840729  1387 ns/op
>> PASS
>> ok  bar.com/benchmarks  23.547s
>>
>> The ratio of timings for Benchmark1 and Benchmark2 are roughly in line 
>> with expectations but I was surprised to see that the timings for 
>> Benchmark3 are now larger than those for Benchmark2.
>>
>> Can anyone explain this?
>>
>> TIA
>> Orson
>>
>

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/5fbe51aa-0ae6-4982-b48c-215af1653f45%40googlegroups.com.


[go-nuts] Re: Bencharking issue with b.StartTimer and b.StopTimer. Was: Benchmark using b.StopTimer and b.StartTimer has unexpected behaviour - to me at least

2020-03-24 Thread Orson Cart
On Tuesday, 24 March 2020 19:51:24 UTC, Jake Montgomery wrote:
>
> Strange. I hope someone has a real answer for you.
>
> In the meantime, you can simplify your example to demonstrate the issue:
>

Thanks for taking a look at the code Jake. Just one question: you have the 
call to b.StopTimer outside of the loop and the call to b.StartTimer 
inside. Was that intentional?

I'd have thought that the call to b.StartTimer would be a no-op after the 
first iteration.






 

>
> package demo_test
>
> import (
> "testing"
> )
>
> var Foo1 []string
> var Count int = 8
>
> func Benchmark1(b *testing.B) {
> for i := 0; i < b.N; i++ {
> Foo1 = foo(Count)
> }
> }
>
> func Benchmark2(b *testing.B) {
> b.StopTimer()
> for i := 0; i < b.N; i++ {
> // Hypothetical setup here 
> b.StartTimer()
> Foo1 = foo(Count)
> b.StopTimer()
> }
> }
>
>
> func foo(count int) []string {
> testData := []string{}
> for i := 0; i < count; i++ {
> testData = append(testData, "a")
> }
>
> return testData
> }
>
> I get:
>
> goos: windows
> goarch: amd64
> Benchmark1-4 2101567   584 ns/op
> Benchmark2-4 100  1668 ns/op
> PASS
>
> So it appears that StopTimer() and StartTimer() are introducing some 
> overhead. I am surprised that it is this large.
>
> Good Luck
>
>
>
> On Tuesday, March 24, 2020 at 12:24:08 PM UTC-4, Orson Cart wrote:
>>
>> I posted this earlier but I realised that the code had a fundamental 
>> error in it. I've corrected here it but the underlying problem still exists.
>>
>> I've recently started using go test's benchmarks support and I'm 
>> particularly interested in understanding the benchmark timer functions. 
>> I've been getting results that I found surprising and I was wondering if 
>> anyone could explain what's going on here.
>>
>> The code below has three benchmarks that each invoke a single function 
>> (foo). The implementation of foo isn't important, it's just there to 
>> consume some time:
>> - foo is called once per iteration in Benchmark1.
>> - It's called twice per iteration in Benchmark2 so I'd expect 
>> Benchmark2's duration to be nominally twice that of Benchmark1.
>> - It's also called twice per iteration in Benchmark3 but the first call 
>> is wrapped in b.StopTimer and b.startTimer calls. Because of this I'd have 
>> expected Benchmark3 to be about the same duration as Benchmark1
>>
>> Apologies for the length of the example but I didn't think it fair to ask 
>> the question and leave anything out.
>>
>> package demo_test
>>
>> import (
>> "strconv"
>> "testing"
>> )
>>
>> var Foo1 []string
>> var Foo2 []string
>> var Count int = 32767
>>
>> func Benchmark1(b *testing.B) {
>> for i := 0; i < b.N; i++{
>> Foo1 = foo(Count)
>> }
>> }
>>
>> func Benchmark2(b *testing.B) {
>> for i := 0; i < b.N; i++{
>> Foo1 = foo(Count)
>> Foo2 = foo(Count)
>> }
>> }
>>
>> func Benchmark3(b *testing.B) {
>> for i := 0; i < b.N; i++{
>> b.StopTimer()
>> Foo1 = foo(Count)
>> b.StartTimer()
>> Foo2 = foo(Count)
>> }
>> }
>>
>> func foo(count int) []string{
>> testData := []string{}
>> for i:= 0; i < count; i++ {
>> testData = append(testData, strconv.Itoa(i))
>> }
>>
>> return testData
>> }
>>
>>
>> When the benchmarks are run the results are as follows:
>>
>> Benchmark1-4 351   3345215 ns/op
>> Benchmark2-4 166   7206582 ns/op
>> Benchmark3-4 334   3457907 ns/op
>> PASS
>> ok  bar.com/benchmarks  6.881s
>>
>> OK benchmark3 is a little slower than Benchmark1 but that's not what's 
>> bothering me. It's this: if I now change Count to something much smaller 
>> the results are a surprise, at least to me. Here are the results when Count 
>> = 8:
>>
>> Benchmark1-4 2706196   442 ns/op
>> Benchmark2-4 1357482   873 ns/op
>> Benchmark3-4  840729  1387 ns/op
>> PASS
>> ok  bar.com/benchmarks  23.547s
>>
>> The ratio of timings for Benchmark1 and Benchmark2 are roughly in line 
>> with expectations but I was surprised to see that the timings for 
>> Benchmark3 are now larger than those for Benchmark2.
>>
>> Can anyone explain this?
>>
>> TIA
>> Orson
>>
>

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/30392378-e6c8-4994-8c82-671383be58b7%40googlegroups.com.


Re: [go-nuts] Bencharking issue with b.StartTimer and b.StopTimer. Was: Benchmark using b.StopTimer and b.StartTimer has unexpected behaviour - to me at least

2020-03-24 Thread Orson Cart
On Tuesday, 24 March 2020 18:50:32 UTC, Michael Jones wrote:
>
> yes
>


...and that is exactly the scenario that I believe is yielding inconsistent 
results:

Given the following function to be benchmarked:

func foo() []string{
testData := []string{}
for i:= 0; i < 8; i++ {
testData = append(testData, strconv.Itoa(i))
}

return testData
}

On my hardware this takes either 454 ns/op or 1322 ns/op depending on how 
it's called:

1st case:
func Benchmark(b *testing.B) {
for i := 0; i < b.N; i++{
Foo1 = foo()// this reports 454 ns/op on my hardware
}
}

2nd case:
func Benchmark(b *testing.B) {
for i := 0; i < b.N; i++{
b.StopTimer()
Foo1 = foo() // This shouldn't be charged against the benchmark. Ignore the 
fact that it's a call to foo, I'm just using it as a means of elapsing some 
time
b.StartTimer()
Foo2 = foo()// this reports a whopping 1322 ns/op on my hardware
}
}

So a call to foo takes over three times more time if *within the loop* we 
stop the timer, do something that takes time and then start the timer 
before calling foo. That's definitely violating the law of least surprise 
for me.
For StopTimer and StartTimer to be of any use I have to believe that they 
actually do stop and start the timer reliably. From those timings I'd say 
that this isn't the case.

As always I may be wrong. I'd just like someone to explain how and I'll be 
a happy chappie :)



 

>
> On Tue, Mar 24, 2020 at 11:48 AM Orson Cart  > wrote:
>
>> On Tuesday, 24 March 2020 18:31:29 UTC, Michael Jones wrote:
>>>
>>> You use them to stop the time charged against your benchmark.
>>>
>>> For example:
>>>
>>> bench:
>>>   stop timer
>>>   generate initial data
>>>   start timer
>>>   do test
>>>
>>
>> Thanks Michael. What if the initial data has to be generated from scratch 
>> on each iteration? Is the following expected to work?
>>
>> bench:
>> b.N Loop
>> stop timer
>> generate new data
>> start timer
>> do test
>>
>>
>>  
>>
>>>
>>> On Tue, Mar 24, 2020 at 10:47 AM Orson Cart  
>>> wrote:
>>>
>>>>
>>>> On Tuesday, 24 March 2020 16:49:55 UTC, Robert Engels wrote:
>>>>>
>>>>> Can you please succinctly explain the problem?
>>>>>
>>>>
>>>> Let's see. Benchmarks can yield incorrect results when b.StopTimer and 
>>>> b.StartTimer are used.
>>>>
>>>> My reasoning:
>>>>
>>>> 1/ I have a benchmark that calls a single function. The reported 
>>>> duration is T.
>>>> 2/ I have another benchmark which invokes the same function twice. I'd 
>>>> expect the reported duration for this to be nominally 2T and within reason 
>>>> it appears to be the case.
>>>> 3/ I have yet another benchmark which also invokes the same function 
>>>> twice but it stops the benchmark timer before the first call and then 
>>>> starts it after the the first call has completed. I'd expect the reported 
>>>> duration to be nominally T again. It isn't. It's closer to 3T on my 
>>>> hardware and I've seen much worse correlation on other hardware - almost 5T
>>>>
>>>> Now it's entirely possible that I'm misunderstanding something about 
>>>> how b.StopTimer and b.StartTimer are intended to be used, hence my post 
>>>> here :)
>>>>  
>>>>
>>>>
>>>>
>>>>
>>>>  
>>>>
>>>>>  
>>>>>
>>>>> On Mar 24, 2020, at 11:24 AM, Orson Cart  
>>>>> wrote:
>>>>>
>>>>> 
>>>>> I posted this earlier but I realised that the code had a fundamental 
>>>>> error in it. I've corrected here it but the underlying problem still 
>>>>> exists.
>>>>>
>>>>> I've recently started using go test's benchmarks support and I'm 
>>>>> particularly interested in understanding the benchmark timer functions. 
>>>>> I've been getting results that I found surprising and I was wondering if 
>>>>> anyone could explain what's going on here.
>>>>>
>>>>> The code below has three benchmarks that each invoke a single function 
>>>>> (foo). The implementation of foo isn't important, it's just there to 
>>>>> consume some time:
>>>>> - foo is called once per iteration in Benchmark1.
>>>>> - It's call

Re: [go-nuts] Bencharking issue with b.StartTimer and b.StopTimer. Was: Benchmark using b.StopTimer and b.StartTimer has unexpected behaviour - to me at least

2020-03-24 Thread Orson Cart
On Tuesday, 24 March 2020 18:31:29 UTC, Michael Jones wrote:
>
> You use them to stop the time charged against your benchmark.
>
> For example:
>
> bench:
>   stop timer
>   generate initial data
>   start timer
>   do test
>

Thanks Michael. What if the initial data has to be generated from scratch 
on each iteration? Is the following expected to work?

bench:
b.N Loop
stop timer
generate new data
start timer
do test


 

>
> On Tue, Mar 24, 2020 at 10:47 AM Orson Cart  > wrote:
>
>>
>> On Tuesday, 24 March 2020 16:49:55 UTC, Robert Engels wrote:
>>>
>>> Can you please succinctly explain the problem?
>>>
>>
>> Let's see. Benchmarks can yield incorrect results when b.StopTimer and 
>> b.StartTimer are used.
>>
>> My reasoning:
>>
>> 1/ I have a benchmark that calls a single function. The reported duration 
>> is T.
>> 2/ I have another benchmark which invokes the same function twice. I'd 
>> expect the reported duration for this to be nominally 2T and within reason 
>> it appears to be the case.
>> 3/ I have yet another benchmark which also invokes the same function 
>> twice but it stops the benchmark timer before the first call and then 
>> starts it after the the first call has completed. I'd expect the reported 
>> duration to be nominally T again. It isn't. It's closer to 3T on my 
>> hardware and I've seen much worse correlation on other hardware - almost 5T
>>
>> Now it's entirely possible that I'm misunderstanding something about how 
>> b.StopTimer and b.StartTimer are intended to be used, hence my post here :)
>>  
>>
>>
>>
>>
>>  
>>
>>>  
>>>
>>> On Mar 24, 2020, at 11:24 AM, Orson Cart  wrote:
>>>
>>> 
>>> I posted this earlier but I realised that the code had a fundamental 
>>> error in it. I've corrected here it but the underlying problem still exists.
>>>
>>> I've recently started using go test's benchmarks support and I'm 
>>> particularly interested in understanding the benchmark timer functions. 
>>> I've been getting results that I found surprising and I was wondering if 
>>> anyone could explain what's going on here.
>>>
>>> The code below has three benchmarks that each invoke a single function 
>>> (foo). The implementation of foo isn't important, it's just there to 
>>> consume some time:
>>> - foo is called once per iteration in Benchmark1.
>>> - It's called twice per iteration in Benchmark2 so I'd expect 
>>> Benchmark2's duration to be nominally twice that of Benchmark1.
>>> - It's also called twice per iteration in Benchmark3 but the first call 
>>> is wrapped in b.StopTimer and b.startTimer calls. Because of this I'd have 
>>> expected Benchmark3 to be about the same duration as Benchmark1
>>>
>>> Apologies for the length of the example but I didn't think it fair to 
>>> ask the question and leave anything out.
>>>
>>> package demo_test
>>>
>>> import (
>>> "strconv"
>>> "testing"
>>> )
>>>
>>> var Foo1 []string
>>> var Foo2 []string
>>> var Count int = 32767
>>>
>>> func Benchmark1(b *testing.B) {
>>> for i := 0; i < b.N; i++{
>>> Foo1 = foo(Count)
>>> }
>>> }
>>>
>>> func Benchmark2(b *testing.B) {
>>> for i := 0; i < b.N; i++{
>>> Foo1 = foo(Count)
>>> Foo2 = foo(Count)
>>> }
>>> }
>>>
>>> func Benchmark3(b *testing.B) {
>>> for i := 0; i < b.N; i++{
>>> b.StopTimer()
>>> Foo1 = foo(Count)
>>> b.StartTimer()
>>> Foo2 = foo(Count)
>>> }
>>> }
>>>
>>> func foo(count int) []string{
>>> testData := []string{}
>>> for i:= 0; i < count; i++ {
>>> testData = append(testData, strconv.Itoa(i))
>>> }
>>>
>>> return testData
>>> }
>>>
>>>
>>> When the benchmarks are run the results are as follows:
>>>
>>> Benchmark1-4 351   3345215 ns/op
>>> Benchmark2-4 166   7206582 ns/op
>>> Benchmark3-4 334   3457907 ns/op
>>> PASS
>>> ok  bar.com/benchmarks  6.881s
>>>
>>> OK benchmark3 is a little slower than Benchmark1 but that's not what's 
>>> bothering me. It's this: if I now change Count to something much smaller 
>>> the 

Re: [go-nuts] Bencharking issue with b.StartTimer and b.StopTimer. Was: Benchmark using b.StopTimer and b.StartTimer has unexpected behaviour - to me at least

2020-03-24 Thread Orson Cart

On Tuesday, 24 March 2020 16:49:55 UTC, Robert Engels wrote:
>
> Can you please succinctly explain the problem?
>

Let's see. Benchmarks can yield incorrect results when b.StopTimer and 
b.StartTimer are used.

My reasoning:

1/ I have a benchmark that calls a single function. The reported duration 
is T.
2/ I have another benchmark which invokes the same function twice. I'd 
expect the reported duration for this to be nominally 2T and within reason 
it appears to be the case.
3/ I have yet another benchmark which also invokes the same function twice 
but it stops the benchmark timer before the first call and then starts it 
after the the first call has completed. I'd expect the reported duration to 
be nominally T again. It isn't. It's closer to 3T on my hardware and I've 
seen much worse correlation on other hardware - almost 5T

Now it's entirely possible that I'm misunderstanding something about how 
b.StopTimer and b.StartTimer are intended to be used, hence my post here :)
 




 

>  
>
> On Mar 24, 2020, at 11:24 AM, Orson Cart  > wrote:
>
> 
> I posted this earlier but I realised that the code had a fundamental error 
> in it. I've corrected here it but the underlying problem still exists.
>
> I've recently started using go test's benchmarks support and I'm 
> particularly interested in understanding the benchmark timer functions. 
> I've been getting results that I found surprising and I was wondering if 
> anyone could explain what's going on here.
>
> The code below has three benchmarks that each invoke a single function 
> (foo). The implementation of foo isn't important, it's just there to 
> consume some time:
> - foo is called once per iteration in Benchmark1.
> - It's called twice per iteration in Benchmark2 so I'd expect Benchmark2's 
> duration to be nominally twice that of Benchmark1.
> - It's also called twice per iteration in Benchmark3 but the first call is 
> wrapped in b.StopTimer and b.startTimer calls. Because of this I'd have 
> expected Benchmark3 to be about the same duration as Benchmark1
>
> Apologies for the length of the example but I didn't think it fair to ask 
> the question and leave anything out.
>
> package demo_test
>
> import (
> "strconv"
> "testing"
> )
>
> var Foo1 []string
> var Foo2 []string
> var Count int = 32767
>
> func Benchmark1(b *testing.B) {
> for i := 0; i < b.N; i++{
> Foo1 = foo(Count)
> }
> }
>
> func Benchmark2(b *testing.B) {
> for i := 0; i < b.N; i++{
> Foo1 = foo(Count)
> Foo2 = foo(Count)
> }
> }
>
> func Benchmark3(b *testing.B) {
> for i := 0; i < b.N; i++{
> b.StopTimer()
> Foo1 = foo(Count)
> b.StartTimer()
> Foo2 = foo(Count)
> }
> }
>
> func foo(count int) []string{
> testData := []string{}
> for i:= 0; i < count; i++ {
> testData = append(testData, strconv.Itoa(i))
> }
>
> return testData
> }
>
>
> When the benchmarks are run the results are as follows:
>
> Benchmark1-4 351   3345215 ns/op
> Benchmark2-4 166   7206582 ns/op
> Benchmark3-4 334   3457907 ns/op
> PASS
> ok  bar.com/benchmarks  6.881s
>
> OK benchmark3 is a little slower than Benchmark1 but that's not what's 
> bothering me. It's this: if I now change Count to something much smaller 
> the results are a surprise, at least to me. Here are the results when Count 
> = 8:
>
> Benchmark1-4 2706196   442 ns/op
> Benchmark2-4 1357482   873 ns/op
> Benchmark3-4  840729  1387 ns/op
> PASS
> ok  bar.com/benchmarks  23.547s
>
> The ratio of timings for Benchmark1 and Benchmark2 are roughly in line 
> with expectations but I was surprised to see that the timings for 
> Benchmark3 are now larger than those for Benchmark2.
>
> Can anyone explain this?
>
> TIA
> Orson
>
> -- 
> 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 golan...@googlegroups.com .
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/38f10940-a770-4fc5-86a9-19cc1371152a%40googlegroups.com
>  
> <https://groups.google.com/d/msgid/golang-nuts/38f10940-a770-4fc5-86a9-19cc1371152a%40googlegroups.com?utm_medium=email_source=footer>
> .
>
>

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/1d291cef-420a-4f80-b719-e0654585c25d%40googlegroups.com.


[go-nuts] Bencharking issue with b.StartTimer and b.StopTimer. Was: Benchmark using b.StopTimer and b.StartTimer has unexpected behaviour - to me at least

2020-03-24 Thread Orson Cart
I posted this earlier but I realised that the code had a fundamental error 
in it. I've corrected here it but the underlying problem still exists.

I've recently started using go test's benchmarks support and I'm 
particularly interested in understanding the benchmark timer functions. 
I've been getting results that I found surprising and I was wondering if 
anyone could explain what's going on here.

The code below has three benchmarks that each invoke a single function 
(foo). The implementation of foo isn't important, it's just there to 
consume some time:
- foo is called once per iteration in Benchmark1.
- It's called twice per iteration in Benchmark2 so I'd expect Benchmark2's 
duration to be nominally twice that of Benchmark1.
- It's also called twice per iteration in Benchmark3 but the first call is 
wrapped in b.StopTimer and b.startTimer calls. Because of this I'd have 
expected Benchmark3 to be about the same duration as Benchmark1

Apologies for the length of the example but I didn't think it fair to ask 
the question and leave anything out.

package demo_test

import (
"strconv"
"testing"
)

var Foo1 []string
var Foo2 []string
var Count int = 32767

func Benchmark1(b *testing.B) {
for i := 0; i < b.N; i++{
Foo1 = foo(Count)
}
}

func Benchmark2(b *testing.B) {
for i := 0; i < b.N; i++{
Foo1 = foo(Count)
Foo2 = foo(Count)
}
}

func Benchmark3(b *testing.B) {
for i := 0; i < b.N; i++{
b.StopTimer()
Foo1 = foo(Count)
b.StartTimer()
Foo2 = foo(Count)
}
}

func foo(count int) []string{
testData := []string{}
for i:= 0; i < count; i++ {
testData = append(testData, strconv.Itoa(i))
}

return testData
}


When the benchmarks are run the results are as follows:

Benchmark1-4 351   3345215 ns/op
Benchmark2-4 166   7206582 ns/op
Benchmark3-4 334   3457907 ns/op
PASS
ok  bar.com/benchmarks  6.881s

OK benchmark3 is a little slower than Benchmark1 but that's not what's 
bothering me. It's this: if I now change Count to something much smaller 
the results are a surprise, at least to me. Here are the results when Count 
= 8:

Benchmark1-4 2706196   442 ns/op
Benchmark2-4 1357482   873 ns/op
Benchmark3-4  840729  1387 ns/op
PASS
ok  bar.com/benchmarks  23.547s

The ratio of timings for Benchmark1 and Benchmark2 are roughly in line with 
expectations but I was surprised to see that the timings for Benchmark3 are 
now larger than those for Benchmark2.

Can anyone explain this?

TIA
Orson

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/38f10940-a770-4fc5-86a9-19cc1371152a%40googlegroups.com.


[go-nuts] Benchmark using b.StopTimer and b.StartTimer has unexpected behaviour - to me at least

2020-03-24 Thread Orson Cart

I posted this earlier but I realised that the code had a fundamental error 
in it. I've corrected here it but the underlying problem still exists.

I've recently started using go test's benchmarks support and I'm 
particularly interested in understanding the benchmark timer functions. 
I've been getting results that I found surprising and I was wondering if 
anyone could explain what's going on here.

The code below has three benchmarks that each invoke a single function 
(foo). The implementation of foo isn't important, it's just there to 
consume some time:
- foo is called once per iteration in Benchmark1.
- It's called twice per iteration in Benchmark2 so I'd expect Benchmark2's 
duration to be nominally twice that of Benchmark1.
- It's also called twice per iteration in Benchmark3 but the first call is 
wrapped in b.StopTimer and b.startTimer calls. Because of this I'd have 
expected Benchmark3 to be about the same duration as Benchmark1

Apologies for the length of the example but I didn't think it fair to ask 
the question and leave anything out.

package demo_test

import (
"strconv"
"testing"
)

var Foo1 []string
var Foo2 []string
var Count int = 32767

func Benchmark1(b *testing.B) {
for i := 0; i < b.N; i++{
Foo1 = foo(Count)
}
}

func Benchmark2(b *testing.B) {
for i := 0; i < b.N; i++{
Foo1 = foo(Count)
Foo2 = foo(Count)
}
}

func Benchmark3(b *testing.B) {
for i := 0; i < b.N; i++{
b.StartTimer()
Foo1 = foo(Count)
b.StopTimer()
Foo2 = foo(Count)
}
}

func setup(count int) []string{
testData := []string{}
for i:= 0; i < count; i++ {
testData = append(testData, strconv.Itoa(i))
}

return testData
}

func foo(count int) []string{
testData := []string{}
for i:= 0; i < count; i++ {
testData = append(testData, strconv.Itoa(i))
}

return testData
}


When the benchmarks are run the results are as follows:

Benchmark1-4 394   2980022 ns/op
Benchmark2-4 196   6113018 ns/op
Benchmark3-4 404   2987882 ns/op
PASS
ok  bar.com/benchmarks  6.671s

OK benchmark3 is a little slower than Benchmark1 but that's not what's 
bothering me. It's this: if I now change Count to something much smaller 
the results are a surprise, at least to me. Here are the results when Count 
= 8:

Benchmark1-4 2600461   460 ns/op
Benchmark2-4 1284936   916 ns/op
Benchmark3-4  705234  1423 ns/op
PASS
ok  bar.com/benchmarks  18.102s

The ratio of timings for Benchmark1 and Benchmark2 are roughly in line with 
expectations but I was surprised to see that the timings for Benchmark3 are 
now larger than those for Benchmark2.

Can anyone explain this?

TIA
Orson

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/97813947-1a1b-479c-963b-c6ef617f66dd%40googlegroups.com.


[go-nuts] Benchmark using b.StopTimer and b.StartTimer has unexpected (to me at least) behaviour

2020-03-24 Thread Orson Cart

I've recently started using go test's benchmarks support and I'm 
particularly interested in understanding the benchmark timer functions. 
I've been getting results that I found surprising and I was wondering if 
anyone could explain what's going on here.

The code below has three benchmarks that each invoke a single function. The 
implementation of foo isn't important, it's just something to take up some 
time:
- foo is called once per iteration in Benchmark1.
- It's called twice per iteration in Benchmark2 so I'd expect Benchmark2's 
duration to be nominally twice that of Benchmark1.
- It's also called twice per iteration in Benchmark3 but the first call is 
wrapped in b.StopTimer and b.startTimer calls. Because of this I'd have 
expected Benchmark3 to be about the same duration as Benchmark1

Apologies for the length of the example but I didn't think it fair to ask 
the question and leave anything out.

package demo_test

import (
"strconv"
"testing"
)

var Foo1 []string
var Foo2 []string
var Count int = 32767

func Benchmark1(b *testing.B) {
for i := 0; i < b.N; i++{
Foo1 = foo(Count)
}
}

func Benchmark2(b *testing.B) {
for i := 0; i < b.N; i++{
Foo1 = foo(Count)
Foo2 = foo(Count)
}
}

func Benchmark3(b *testing.B) {
for i := 0; i < b.N; i++{
b.StartTimer()
Foo1 = foo(Count)
b.StopTimer()
Foo2 = foo(Count)
}
}

func setup(count int) []string{
testData := []string{}
for i:= 0; i < count; i++ {
testData = append(testData, strconv.Itoa(i))
}

return testData
}

func foo(count int) []string{
testData := []string{}
for i:= 0; i < count; i++ {
testData = append(testData, strconv.Itoa(i))
}

return testData
}


When the benchmarks are run the results are as follows:

Benchmark1-4 432   2805980 ns/op
Benchmark2-4 199   5930258 ns/op
Benchmark3-4 406   2909451 ns/op
PASS
ok  bar.com/benchmarks  6.618s

OK benchmark3 is a little slower than Benchmark1 but that's not what's 
bothering me. It's this: if I now change Count to something much smaller 
the results are a surprise, at least to me. Here are the results when Count 
= 8:

Benchmark1-4 2640558   453 ns/op
Benchmark2-4 1330572   898 ns/op
Benchmark3-4  943780  1292 ns/op
PASS
ok  bar.com/benchmarks  35.257s

The timings for Benchmark1 and Benchmark2 are roughly in line with 
expectations but I was surprised to see that the timings for Benchmark3 are 
now larger than those for Benchmark2.

Can anyone explain this?

TIA
Orson

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/acbd4ca8-4199-4662-aca7-abf87b48b5f2%40googlegroups.com.


Re: [go-nuts] Benchmarking code that mutates its input data

2020-03-19 Thread Orson Cart
On Wednesday, 18 March 2020 15:50:33 UTC, Sam Whited wrote:
>
> Just call b.ResetTimer() after setting up your data: 
> https://godoc.org/testing#B.ResetTimer 
>

Thanks, I'll take a look
 

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/8245d0ae-9fd2-4022-a0c0-109f3fea76c7%40googlegroups.com.


Re: [go-nuts] Benchmarking code that mutates its input data

2020-03-19 Thread Orson Cart
On Wednesday, 18 March 2020 17:53:05 UTC, Robert Engels wrote:
>
> The test package has methods to disable the timing - wrap the setup in 
> these. 
>

Thanks. I guess you're referring to StoptTimer, StartTimer and ResetTimer?

I think that in my case ResetTimer will do the trick. Unless I'm mistaken 
StartTimer and StopTimer are useful in more complex scenarios.

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/31cce81a-ca4c-4f7b-bb35-6b1fde3c093e%40googlegroups.com.


Re: [go-nuts] Benchmarking code that mutates its input data

2020-03-19 Thread Orson Cart


On Wednesday, 18 March 2020 15:50:33 UTC, Sam Whited wrote:
>
> Just call b.ResetTimer() after setting up your data: 
> https://godoc.org/testing#B.ResetTimer 
>
>
Thanks, I'll take a look

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/3c492bd7-389a-4cf4-9221-1f4779c91221%40googlegroups.com.


[go-nuts] Benchmarking code that mutates its input data

2020-03-18 Thread Orson Cart

We have a slice containing a mix of data items, some of which are deemed to 
be 'valid', some 'invalid'. We need to remove the invalid items.

In the current implementation we have a function which takes the slice as 
input and removes the invalid' elements from it in place i.e. not from a 
copy.  So, after the function has completed, the slice will no longer 
contain any of the invalid elements.

We have alternative approaches to doing this but ideally we'd like to 
benchmark each. However we're struggling to set up the test data for this 
one because after the first call there will be no data to change - if the 
profiler were to call the function 1000 times, only the first call will 
have done any actual work. To make the benchmarked function do the same 
work each time we'd have to set up fresh data for each call to the 
function. We can do that but we don't want that setup to show in the timing 
for the benchmark.

Does anyone know of a solution to this?

TIA,
Orson

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/0678f930-e5de-4e2c-af6b-58d1ad51daae%40googlegroups.com.


[go-nuts] Information hiding within a package

2020-01-21 Thread Orson Cart

I'm still new to using Go so maybe I'm missing something of the 'culture' 
but I find that I'd often like to be able to hide implementation detail on 
a level that is more finely grained than the package.

I'm aware that using case it's possible to define for instance struct 
members that are not accessible to code outside of the struct's package.

I'm also aware that you can employ this concept such that a package can 
define a public interface which can be *used* by code outside of the 
package but which effectively can't be *implemented* by code outside the 
package. There's an example of this in section 2 here:
https://www.onebigfluke.com/2014/04/gos-power-is-in-emergent-behavior.html

I guess I'm looking for something like opaque pointers which were employed 
to good effect in C to hide implementation details from 'peer' source 
files: https://en.wikipedia.org/wiki/Opaque_pointer#C

If as I suspect there is no way of achieving what I'm looking for, does 
anyone know of a good reason why this level of information hiding isn't 
possible in Go? Do experienced Go developers just not feel the need for it?

TIA
Orson


-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/66e5cf32-9837-433d-82d6-9c1af2ebe1c9%40googlegroups.com.


Re: [go-nuts] Difference with function returning struct and function returning pointer to struct

2019-11-20 Thread Orson Cart
On Wednesday, 20 November 2019 17:55:59 UTC, Ian Lance Taylor wrote:
>
> The other kind of answer is that if a function returns a pointer to a 
> struct, a value of type *employee, then it's normal for that something 
> else to have a copy of that pointer, perhaps some data structure or 
> global variable.  In your simple example that is the global variable 
> "dilbert".  So it makes sense to permit setting a field of the result 
> of calling getEmployee(), a value of type *employee, as setting that 
> field will change the global variable "dilbert".  But when 
> getEmployee() does not return a pointer, but just returns a value of 
> type "employee", then that is a copy of the value in the global 
> variable.  Changing a field in that copy won't change anything.  The 
> assignment will be made, and then the result will be discarded.  Since 
> that operation is useless, the language does not permit it. 
>

 Hi Ian and thanks for your prompt reply. This is exactly the kind of 
explanation that I was looking for and it makes complete sense now.

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/7fb82fec-9430-4c5e-8005-ce86cda91921%40googlegroups.com.


Re: [go-nuts] Difference with function returning struct and function returning pointer to struct

2019-11-20 Thread Orson Cart
On Wednesday, 20 November 2019 17:55:00 UTC, Thomas Bushnell, BSG wrote:

but the return value of a function is not addressable (it's not a variable, 
pointer, etc etc).


Hi Thomas. Apologies, I said "assignable" when I meant "addressable". I was 
curious as to why a struct returned from a function is not addressable but 
I understand now.

Thanks for your prompt reply.

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/5c7bf010-eecb-42d0-a45b-9d73352a53e5%40googlegroups.com.


[go-nuts] Difference with function returning struct and function returning pointer to struct

2019-11-20 Thread Orson Cart

I'm a newbie to Go having used C and C++ in the past and I'm puzzled about 
something I've just seen.

In the following code getEmployee returns a pointer to a struct. The return 
value is then dereferenced. This code compiles and runs fine:

package main

type employee struct {
ID   int
name string
}

var dilbert employee

func main() {

getEmployee().name = "dilbert"
}

func getEmployee() *employee {
return 
}

However if I modify getEmployee as follows, I get a compilation error:

func getEmployee() employee {
return dilbert
}

The error is: cannot assign to getEmployee().name

I assume that it revolves around "assignability" but I'm struggling to 
understand why.

Can anyone tell me why this is?

TIA,
Orson


-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/aaead2ec-b5b8-48d0-80e5-5275eeb583c2%40googlegroups.com.