You can make it a teensy bit more efficient by copying the pointed-at value 
directly and skipping an allocation. (This isn’t safe in general but works for 
sha256.digest in this case.) I refactored away the string copies etc to focus 
on the actual hashing.

https://play.golang.org/p/TxN2ni1o4v<https://play.golang.org/p/1poL3XvR6D>

jb@unu:~/tmp $ go test -bench . -benchmem
goos: darwin
goarch: amd64
BenchmarkHash-8          2000000        748 ns/op        0 B/op        0 
allocs/op
BenchmarkCopyHash0-8     2000000        710 ns/op      128 B/op        1 
allocs/op
BenchmarkCopyHash1-8     3000000        564 ns/op        0 B/op        0 
allocs/op
PASS

Maybe you could squeeze out a few more nanoseconds by forking the sha256 
package and adding a copy method direcly on sha256.digest, avoiding the reflect 
roundtrip.

Depending on your CPU architecture, check out 
https://github.com/minio/sha256-simd as well.

//jb

On 8 Nov 2017, at 13:54, Christian LeMoussel 
<cnh...@gmail.com<mailto:cnh...@gmail.com>> wrote:

Hi,

I want to calculate hash on 3 strings. First string is always the same, the 
other may vary.
The first approach is to calculate the hash each time for the 3 strings 
(BenchmarkHash)
Another approach would be to calculate once for the first string, and then 
reuse this hash to calculate the hash with the other 2 
strings(BenchmarkCopyHash)
The difficulty is that sha256.New() returns a pointer, we have to copy the 
first hash. To do this, I created the function copyHash()
But the performances are not exceptional.

Do you have another idea to do this in efficient way?


BenchmarkHash-8                  1000000              1761 ns/op             
176 B/op          4 allocs/op
BenchmarkCopyHash-8              1000000              1519 ns/op             
240 B/op          4 allocs/op


var m1 = strings.Repeat("a", 64)
var m2 = strings.Repeat("b", 48)
var m3 = strings.Repeat("c", 32)

func BenchmarkHash(b *testing.B) {
    var (
        d hash.Hash
    )

    d = sha256.New()
    for n := 0; n < b.N; n++ {
        d.Reset()
        d.Write([]byte(m1))
        d.Write([]byte(m2))
        d.Write([]byte(m3))
        d.Sum(nil)
    }
}
func BenchmarkCopyHash(b *testing.B) {
    var (
        d1 hash.Hash
        d2 hash.Hash
    )

    d1 = sha256.New()
    d1.Write([]byte(m1))

    for n := 0; n < b.N; n++ {
        d2 = copyHash(d1)
        d2.Write([]byte(m2))
        d2.Write([]byte(m3))
        d2.Sum(nil)
    }
}

func copyHash(src hash.Hash) hash.Hash {
    typ := reflect.TypeOf(src).Elem()
    val := reflect.ValueOf(src).Elem()
    elem := reflect.New(typ).Elem()
    elem.Set(val)
    return elem.Addr().Interface().(hash.Hash)
}







--
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<mailto:golang-nuts+unsubscr...@googlegroups.com>.
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to