diff --git a/src/libfetchers/github.cc b/src/libfetchers/github.cc
index 8675a5a662d5c466b09cb6d76fcca2e79c15bf4b..0bee1d6b3f91399593f397cc112209fadb62f5df 100644
--- a/src/libfetchers/github.cc
+++ b/src/libfetchers/github.cc
@@ -76,7 +76,7 @@ struct GitHubInput : Input
                 readFile(
                     store->toRealPath(
                         downloadFile(store, url, "source", false).storePath)));
-            rev = Hash(json["sha"], htSHA1);
+            rev = Hash(std::string { json["sha"] }, htSHA1);
             debug("HEAD revision for '%s' is %s", url, rev->gitRev());
         }
 
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc
index 0645fca84160819c371f6c35f237ea4b63d74af7..f6901bf422cb0dafee57da6b493ec8e600c1d103 100644
--- a/src/libstore/store-api.cc
+++ b/src/libstore/store-api.cc
@@ -779,7 +779,7 @@ bool ValidPathInfo::isContentAddressed(const Store & store) const
     };
 
     if (hasPrefix(ca, "text:")) {
-        Hash hash(std::string(ca, 5));
+        Hash hash(ca.substr(5));
         if (store.makeTextPath(path.name(), hash, references) == path)
             return true;
         else
@@ -788,7 +788,7 @@ bool ValidPathInfo::isContentAddressed(const Store & store) const
 
     else if (hasPrefix(ca, "fixed:")) {
         FileIngestionMethod recursive { ca.compare(6, 2, "r:") == 0 };
-        Hash hash(std::string(ca, recursive == FileIngestionMethod::Recursive ? 8 : 6));
+        Hash hash(ca.substr(recursive == FileIngestionMethod::Recursive ? 8 : 6));
         auto refs = cloneStorePathSet(references);
         bool hasSelfReference = false;
         if (refs.count(path)) {
diff --git a/src/libutil/hash.cc b/src/libutil/hash.cc
index c935f05eb537a32b4e29ab384a9ffe925938aefd..460d479a32f9b5100ebc064283031251f264b2c3 100644
--- a/src/libutil/hash.cc
+++ b/src/libutil/hash.cc
@@ -125,7 +125,7 @@ std::string Hash::to_string(Base base, bool includeType) const
 }
 
 
-Hash::Hash(const std::string & s, HashType type)
+Hash::Hash(std::string_view s, HashType type)
     : type(type)
 {
     size_t pos = 0;
@@ -194,7 +194,7 @@ Hash::Hash(const std::string & s, HashType type)
     }
 
     else if (isSRI || size == base64Len()) {
-        auto d = base64Decode(std::string(s, pos));
+        auto d = base64Decode(s.substr(pos));
         if (d.size() != hashSize)
             throw BadHash("invalid %s hash '%s'", isSRI ? "SRI" : "base-64", s);
         assert(hashSize);
diff --git a/src/libutil/hash.hh b/src/libutil/hash.hh
index 5080539b2d893eb79dcbadecee59ecf6764f9fcc..180fb76334d738b4085519ddd84e13020ac35583 100644
--- a/src/libutil/hash.hh
+++ b/src/libutil/hash.hh
@@ -42,7 +42,7 @@ struct Hash
        Subresource Integrity hash expression). If the 'type' argument
        is htUnknown, then the hash type must be specified in the
        string. */
-    Hash(const std::string & s, HashType type = htUnknown);
+    Hash(std::string_view s, HashType type = htUnknown);
 
     void init();
 
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index e0a99152b56e2d89bbb48c3590799665639755b5..b66447e08ccd4100ae61450b61c53912e729d1f8 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -1314,7 +1314,7 @@ bool statusOk(int status)
 }
 
 
-bool hasPrefix(const string & s, const string & prefix)
+bool hasPrefix(std::string_view s, std::string_view prefix)
 {
     return s.compare(0, prefix.size(), prefix) == 0;
 }
@@ -1408,7 +1408,7 @@ std::string filterANSIEscapes(const std::string & s, bool filterAll, unsigned in
 static char base64Chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
 
-string base64Encode(const string & s)
+string base64Encode(std::string_view s)
 {
     string res;
     int data = 0, nbits = 0;
@@ -1429,7 +1429,7 @@ string base64Encode(const string & s)
 }
 
 
-string base64Decode(const string & s)
+string base64Decode(std::string_view s)
 {
     bool init = false;
     char decode[256];
diff --git a/src/libutil/util.hh b/src/libutil/util.hh
index 4b117f9bc0543fb1f6113d41f9f9f6fc95345484..c95232317c3b812a414598b184ed365c5e367873 100644
--- a/src/libutil/util.hh
+++ b/src/libutil/util.hh
@@ -416,7 +416,7 @@ template<class N> bool string2Float(const string & s, N & n)
 
 
 /* Return true iff `s' starts with `prefix'. */
-bool hasPrefix(const string & s, const string & prefix);
+bool hasPrefix(std::string_view s, std::string_view prefix);
 
 
 /* Return true iff `s' ends in `suffix'. */
@@ -455,8 +455,8 @@ std::string filterANSIEscapes(const std::string & s,
 
 
 /* Base64 encoding/decoding. */
-string base64Encode(const string & s);
-string base64Decode(const string & s);
+string base64Encode(std::string_view s);
+string base64Decode(std::string_view s);
 
 
 /* Get a value for the specified key from an associate container. */