use sync/atomic.Value for concurrency safe caching
diff --git a/homedir.go b/homedir.go
index 5cff371..2f54ed6 100644
--- a/homedir.go
+++ b/homedir.go
@@ -8,32 +8,42 @@
 	"path/filepath"
 	"runtime"
 	"strings"
+	"sync/atomic"
 )
 
-var homedir string
+// DisableCache will disable caching of the home directory. Caching is enabled
+// by default.
+var DisableCache bool
+
+var homedirCache atomic.Value
 
 // Dir returns the home directory for the executing user.
 //
 // This uses an OS-specific method for discovering the home directory.
 // An error is returned if a home directory cannot be detected.
 func Dir() (string, error) {
-	if homedir != "" {
-		return homedir, nil
+	if !DisableCache {
+		cached := homedirCache.Load()
+		if cached != nil && cached != "" {
+			return cached.(string), nil
+		}
 	}
 
+	var result string
 	var err error
 	if runtime.GOOS == "windows" {
-		homedir, err = dirWindows()
+		result, err = dirWindows()
 	} else {
 		// Unix-like system, so just assume Unix
-		homedir, err = dirUnix()
+		result, err = dirUnix()
 	}
 
 	if err != nil {
 		return "", err
 	}
 
-	return homedir, nil
+	homedirCache.Store(result)
+	return result, nil
 }
 
 // Expand expands the path to include the home directory if the path
diff --git a/homedir_test.go b/homedir_test.go
index ddc24ee..c34dbc7 100644
--- a/homedir_test.go
+++ b/homedir_test.go
@@ -17,6 +17,18 @@
 	return deferFunc
 }
 
+func BenchmarkDir(b *testing.B) {
+	// We do this for any "warmups"
+	for i := 0; i < 10; i++ {
+		Dir()
+	}
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		Dir()
+	}
+}
+
 func TestDir(t *testing.T) {
 	u, err := user.Current()
 	if err != nil {
@@ -86,6 +98,8 @@
 		}
 	}
 
+	DisableCache = true
+	defer func() { DisableCache = false }()
 	defer patchEnv("HOME", "/custom/path/")()
 	expected := "/custom/path/foo/bar"
 	actual, err := Expand("~/foo/bar")