Merge pull request #6 from mtchavez/master

Adding benchmark tests
diff --git a/mapstructure_benchmark_test.go b/mapstructure_benchmark_test.go
new file mode 100644
index 0000000..b50ac36
--- /dev/null
+++ b/mapstructure_benchmark_test.go
@@ -0,0 +1,243 @@
+package mapstructure
+
+import (
+	"testing"
+)
+
+func Benchmark_Decode(b *testing.B) {
+	type Person struct {
+		Name   string
+		Age    int
+		Emails []string
+		Extra  map[string]string
+	}
+
+	input := map[string]interface{}{
+		"name":   "Mitchell",
+		"age":    91,
+		"emails": []string{"one", "two", "three"},
+		"extra": map[string]string{
+			"twitter": "mitchellh",
+		},
+	}
+
+	var result Person
+	for i := 0; i < b.N; i++ {
+		Decode(input, &result)
+	}
+}
+
+func Benchmark_DecodeBasic(b *testing.B) {
+	input := map[string]interface{}{
+		"vstring": "foo",
+		"vint":    42,
+		"Vuint":   42,
+		"vbool":   true,
+		"Vfloat":  42.42,
+		"vsilent": true,
+		"vdata":   42,
+	}
+
+	var result Basic
+	for i := 0; i < b.N; i++ {
+		Decode(input, &result)
+	}
+}
+
+func Benchmark_DecodeEmbedded(b *testing.B) {
+	input := map[string]interface{}{
+		"vstring": "foo",
+		"Basic": map[string]interface{}{
+			"vstring": "innerfoo",
+		},
+		"vunique": "bar",
+	}
+
+	var result Embedded
+	for i := 0; i < b.N; i++ {
+		Decode(input, &result)
+	}
+}
+
+func Benchmark_DecodeTypeConversion(b *testing.B) {
+	input := map[string]interface{}{
+		"IntToFloat":    42,
+		"IntToUint":     42,
+		"IntToBool":     1,
+		"IntToString":   42,
+		"UintToInt":     42,
+		"UintToFloat":   42,
+		"UintToBool":    42,
+		"UintToString":  42,
+		"BoolToInt":     true,
+		"BoolToUint":    true,
+		"BoolToFloat":   true,
+		"BoolToString":  true,
+		"FloatToInt":    42.42,
+		"FloatToUint":   42.42,
+		"FloatToBool":   42.42,
+		"FloatToString": 42.42,
+		"StringToInt":   "42",
+		"StringToUint":  "42",
+		"StringToBool":  "1",
+		"StringToFloat": "42.42",
+		"SliceToMap":    []interface{}{},
+		"MapToSlice":    map[string]interface{}{},
+	}
+
+	var resultStrict TypeConversionResult
+	for i := 0; i < b.N; i++ {
+		Decode(input, &resultStrict)
+	}
+}
+
+func Benchmark_DecodeMap(b *testing.B) {
+	input := map[string]interface{}{
+		"vfoo": "foo",
+		"vother": map[interface{}]interface{}{
+			"foo": "foo",
+			"bar": "bar",
+		},
+	}
+
+	var result Map
+	for i := 0; i < b.N; i++ {
+		Decode(input, &result)
+	}
+}
+
+func Benchmark_DecodeMapOfStruct(b *testing.B) {
+	input := map[string]interface{}{
+		"value": map[string]interface{}{
+			"foo": map[string]string{"vstring": "one"},
+			"bar": map[string]string{"vstring": "two"},
+		},
+	}
+
+	var result MapOfStruct
+	for i := 0; i < b.N; i++ {
+		Decode(input, &result)
+	}
+}
+
+func Benchmark_DecodeSlice(b *testing.B) {
+	input := map[string]interface{}{
+		"vfoo": "foo",
+		"vbar": []string{"foo", "bar", "baz"},
+	}
+
+	var result Slice
+	for i := 0; i < b.N; i++ {
+		Decode(input, &result)
+	}
+}
+
+func Benchmark_DecodeSliceOfStruct(b *testing.B) {
+	input := map[string]interface{}{
+		"value": []map[string]interface{}{
+			{"vstring": "one"},
+			{"vstring": "two"},
+		},
+	}
+
+	var result SliceOfStruct
+	for i := 0; i < b.N; i++ {
+		Decode(input, &result)
+	}
+}
+
+func Benchmark_DecodeWeaklyTypedInput(b *testing.B) {
+	type Person struct {
+		Name   string
+		Age    int
+		Emails []string
+	}
+
+	// This input can come from anywhere, but typically comes from
+	// something like decoding JSON, generated by a weakly typed language
+	// such as PHP.
+	input := map[string]interface{}{
+		"name":   123,                      // number => string
+		"age":    "42",                     // string => number
+		"emails": map[string]interface{}{}, // empty map => empty array
+	}
+
+	var result Person
+	config := &DecoderConfig{
+		WeaklyTypedInput: true,
+		Result:           &result,
+	}
+
+	decoder, err := NewDecoder(config)
+	if err != nil {
+		panic(err)
+	}
+
+	for i := 0; i < b.N; i++ {
+		decoder.Decode(input)
+	}
+}
+
+func Benchmark_DecodeMetadata(b *testing.B) {
+	type Person struct {
+		Name string
+		Age  int
+	}
+
+	input := map[string]interface{}{
+		"name":  "Mitchell",
+		"age":   91,
+		"email": "foo@bar.com",
+	}
+
+	var md Metadata
+	var result Person
+	config := &DecoderConfig{
+		Metadata: &md,
+		Result:   &result,
+	}
+
+	decoder, err := NewDecoder(config)
+	if err != nil {
+		panic(err)
+	}
+
+	for i := 0; i < b.N; i++ {
+		decoder.Decode(input)
+	}
+}
+
+func Benchmark_DecodeMetadataEmbedded(b *testing.B) {
+	input := map[string]interface{}{
+		"vstring": "foo",
+		"vunique": "bar",
+	}
+
+	var md Metadata
+	var result EmbeddedSquash
+	config := &DecoderConfig{
+		Metadata: &md,
+		Result:   &result,
+	}
+
+	decoder, err := NewDecoder(config)
+	if err != nil {
+		b.Fatalf("err: %s", err)
+	}
+
+	for i := 0; i < b.N; i++ {
+		decoder.Decode(input)
+	}
+}
+
+func Benchmark_DecodeTagged(b *testing.B) {
+	input := map[string]interface{}{
+		"foo": "bar",
+		"bar": "value",
+	}
+
+	var result Tagged
+	for i := 0; i < b.N; i++ {
+		Decode(input, &result)
+	}
+}