unmarshal: replace manual array element copy with reflect.Copy

This commit also adds a benchmark for array unmarshaling. The difference
is staggering.

name                   old time/op    new time/op    delta
LargeArrayUnmarshal-4    23.4µs ± 2%     0.4µs ± 2%  -98.49%  (p=0.000 n=9+9)

name                   old alloc/op   new alloc/op   delta
LargeArrayUnmarshal-4     96.0B ± 0%    128.0B ± 0%  +33.33%  (p=0.000 n=10+10)

name                   old allocs/op  new allocs/op  delta
LargeArrayUnmarshal-4      3.00 ± 0%      4.00 ± 0%  +33.33%  (p=0.000 n=10+10)
diff --git a/unmarshal.go b/unmarshal.go
index 342243e..63b4b1d 100644
--- a/unmarshal.go
+++ b/unmarshal.go
@@ -188,11 +188,8 @@
 			if val.Len() < len(b) {
 				panic(fmt.Errorf("plist: attempted to unmarshal %d bytes into a byte array of size %d", len(b), val.Len()))
 			}
-
-			// slow path -- arrays don't support .SetBytes
-			for i, v := range b {
-				val.Index(i).Set(reflect.ValueOf(v))
-			}
+			sval := reflect.ValueOf(b)
+			reflect.Copy(val, sval)
 		}
 	case cfUID:
 		if val.Type() == uidType {
diff --git a/unmarshal_test.go b/unmarshal_test.go
index eaf3cdb..c673793 100644
--- a/unmarshal_test.go
+++ b/unmarshal_test.go
@@ -30,3 +30,13 @@
 		d.unmarshal(plistValueTree, reflect.ValueOf(&xval))
 	}
 }
+
+func BenchmarkLargeArrayUnmarshal(b *testing.B) {
+	var xval [1024]byte
+	pval := cfData(make([]byte, 1024))
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		d := &Decoder{}
+		d.unmarshal(pval, reflect.ValueOf(&xval))
+	}
+}