From 9e92928f7ec520307f6032732894068d09b4f7fb Mon Sep 17 00:00:00 2001 From: Paulo Morgado <470455+paulomorgado@users.noreply.github.com> Date: Fri, 29 May 2026 14:47:11 +0100 Subject: [PATCH] Reduce string allocations in sys helpers Apply string interpolation and span-based trimming updates under src/SIPSorcery/sys. Keep the KeyValuePair deconstruction helper because current transaction code still depends on it. --- src/SIPSorcery/sys/Crypto/Crypto.cs | 4 +-- src/SIPSorcery/sys/Crypto/PasswordHash.cs | 4 +-- .../sys/Formatting/NumberFormatting.cs | 18 ++++++------ src/SIPSorcery/sys/Net/IPSocket.cs | 28 ++++++++++--------- src/SIPSorcery/sys/TypeExtensions.cs | 6 ++-- 5 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/SIPSorcery/sys/Crypto/Crypto.cs b/src/SIPSorcery/sys/Crypto/Crypto.cs index bf1789cfe..d8cbe673d 100644 --- a/src/SIPSorcery/sys/Crypto/Crypto.cs +++ b/src/SIPSorcery/sys/Crypto/Crypto.cs @@ -293,7 +293,7 @@ private static FileStream GetFileStream(string filepath) if (!File.Exists(filepath)) { logger.LogError("Cannot open a non-existent file for a hash operation, {FilePath}.", filepath); - throw new IOException("Cannot open a non-existent file for a hash operation, " + filepath + "."); + throw new IOException($"Cannot open a non-existent file for a hash operation, {filepath}."); } // Open the file. @@ -303,7 +303,7 @@ private static FileStream GetFileStream(string filepath) { inputStream.Close(); logger.LogError("Cannot perform a hash operation on an empty file, {FilePath}.", filepath); - throw new IOException("Cannot perform a hash operation on an empty file, " + filepath + "."); + throw new IOException($"Cannot perform a hash operation on an empty file, {filepath}."); } return inputStream; diff --git a/src/SIPSorcery/sys/Crypto/PasswordHash.cs b/src/SIPSorcery/sys/Crypto/PasswordHash.cs index 3beee8029..9e04dc642 100644 --- a/src/SIPSorcery/sys/Crypto/PasswordHash.cs +++ b/src/SIPSorcery/sys/Crypto/PasswordHash.cs @@ -42,7 +42,7 @@ public static string GenerateSalt(int? explicitIterations = null) { if (explicitIterations.HasValue && explicitIterations.Value < RFC289_MINIMUM_ITERATIONS) { - throw new ArgumentException("Cannot be less than " + RFC289_MINIMUM_ITERATIONS, "explicitIterations"); + throw new ArgumentException($"Cannot be less than {RFC289_MINIMUM_ITERATIONS}", "explicitIterations"); } byte[] salt = new byte[SALT_SIZE]; @@ -50,7 +50,7 @@ public static string GenerateSalt(int? explicitIterations = null) var iterations = (explicitIterations ?? RFC289_MINIMUM_ITERATIONS).ToString("X"); - return iterations + "." + Convert.ToBase64String(salt); + return $"{iterations}.{Convert.ToBase64String(salt)}"; } /// diff --git a/src/SIPSorcery/sys/Formatting/NumberFormatting.cs b/src/SIPSorcery/sys/Formatting/NumberFormatting.cs index db1d8161f..b62544c49 100644 --- a/src/SIPSorcery/sys/Formatting/NumberFormatting.cs +++ b/src/SIPSorcery/sys/Formatting/NumberFormatting.cs @@ -25,22 +25,22 @@ public static string ToSIFormat(double number, int decimalPlaces) if (number > 1000000000000) { double teraNumber = Math.Round((double)(number / (double)100000000000), decimalPlaces); - return teraNumber.ToString() + "T"; + return $"{teraNumber}T"; } if (number > 1000000000) { double gigaNumber = Math.Round((double)(number / (double)100000000), decimalPlaces); - return gigaNumber.ToString() + "G"; + return $"{gigaNumber}G"; } else if (number > 1000000) { double kiloNumber = Math.Round((double)(number / (double)1000000), decimalPlaces); - return kiloNumber.ToString() + "M"; + return $"{kiloNumber}M"; } else if (number > 1000) { double kiloNumber = Math.Round((double)(number / (double)1000), decimalPlaces); - return kiloNumber.ToString() + "k"; + return $"{kiloNumber}k"; } else { @@ -53,26 +53,26 @@ private static string ToSIByteFormat(double number, int decimalPlaces, string su if (number > 1099511627776) { double teraNumber = Math.Round((double)(number / (double)1099511627776), decimalPlaces); - return teraNumber.ToString() + "T" + suffix; + return $"{teraNumber}T{suffix}"; } if (number > 1073741824) { double gigaNumber = Math.Round((double)(number / (double)1073741824), decimalPlaces); - return gigaNumber.ToString() + "G" + suffix; + return $"{gigaNumber}G{suffix}"; } else if (number > 1048576) { double kiloNumber = Math.Round((double)(number / (double)1048576), decimalPlaces); - return kiloNumber.ToString() + "M" + suffix; + return $"{kiloNumber}M{suffix}"; } else if (number > 1024) { double kiloNumber = Math.Round((double)(number / (double)1024), decimalPlaces); - return kiloNumber.ToString() + "K" + suffix; + return $"{kiloNumber}K{suffix}"; } else { - return Math.Round((double)number, decimalPlaces).ToString() + suffix; + return $"{Math.Round((double)number, decimalPlaces)}{suffix}"; } } diff --git a/src/SIPSorcery/sys/Net/IPSocket.cs b/src/SIPSorcery/sys/Net/IPSocket.cs index 425a86d15..f5eb689fb 100644 --- a/src/SIPSorcery/sys/Net/IPSocket.cs +++ b/src/SIPSorcery/sys/Net/IPSocket.cs @@ -44,8 +44,10 @@ public class IPSocket /// public static string GetSocketString(IPEndPoint endPoint) { - string format = (endPoint.Address.AddressFamily == AddressFamily.InterNetworkV6) ? "[{0}]:{1}" : "{0}:{1}"; - return string.Format(format, endPoint.Address.ToString(), endPoint.Port.ToString(NumberFormatInfo.InvariantInfo)); + var address = endPoint.Address.ToString(); + var port = endPoint.Port.ToString(NumberFormatInfo.InvariantInfo); + + return endPoint.Address.AddressFamily == AddressFamily.InterNetworkV6 ? $"[{address}]:{port}" : $"{address}:{port}"; } /// @@ -123,7 +125,7 @@ public static string ParseHostFromSocket(string socket) { string host = socket; - if (socket != null && socket.Trim().Length > 0 && socket.IndexOf(':') != -1) + if (!string.IsNullOrWhiteSpace(socket) && socket.IndexOf(':') != -1) { host = socket.Substring(0, socket.LastIndexOf(':')).Trim(); } @@ -154,14 +156,14 @@ public static int ParsePortFromSocket(string socket) } // Look to see if this is IPv4 with a port (IPv6 will have another colon) // If it's a host name there will also not be another ':'. - else if (socket.Substring(0, lastColonPos).LastIndexOf(':') != -1) + else if (socket.AsSpan(0, lastColonPos).LastIndexOf(':') != -1) { // This is an IPv6 address WITHOUT a port. lastColonPos = -1; } } - if (socket != null && socket.Trim().Length > 0 && lastColonPos != -1) + if (!string.IsNullOrWhiteSpace(socket) && lastColonPos != -1) { port = Convert.ToInt32(socket.Substring(lastColonPos + 1).Trim()); } @@ -176,7 +178,7 @@ public static int ParsePortFromSocket(string socket) /// true/false public static bool IsIPAddress(string socket) { - if (socket == null || socket.Trim().Length == 0) + if (string.IsNullOrWhiteSpace(socket)) { return false; } @@ -310,7 +312,7 @@ public static bool Parse(string endpointstring, out string host, out int port) } else { - throw new FormatException(string.Format("Invalid endpoint ipaddress '{0}'", endpointstring)); + throw new FormatException($"Invalid endpoint ipaddress '{endpointstring}'"); } return rc; @@ -327,7 +329,7 @@ public static IPEndPoint Parse(string endpointstring, int defaultport = -1) (defaultport < IPEndPoint.MinPort || defaultport > IPEndPoint.MaxPort)) { - throw new ArgumentException(string.Format("Invalid default port '{0}'", defaultport)); + throw new ArgumentException($"Invalid default port '{defaultport}'"); } string[] values = endpointstring.Split(new char[] { ':' }); @@ -356,7 +358,7 @@ public static IPEndPoint Parse(string endpointstring, int defaultport = -1) } catch { - throw new FormatException(string.Format("Invalid endpoint ipaddress '{0}'", endpointstring)); + throw new FormatException($"Invalid endpoint ipaddress '{endpointstring}'"); } } } @@ -377,7 +379,7 @@ public static IPEndPoint Parse(string endpointstring, int defaultport = -1) } else { - throw new FormatException(string.Format("Invalid endpoint ipaddress '{0}'", endpointstring)); + throw new FormatException($"Invalid endpoint ipaddress '{endpointstring}'"); } if (port == -1) @@ -396,7 +398,7 @@ private static int getPort(string p) || port < IPEndPoint.MinPort || port > IPEndPoint.MaxPort) { - throw new FormatException(string.Format("Invalid end point port '{0}'", p)); + throw new FormatException($"Invalid end point port '{p}'"); } return port; @@ -410,13 +412,13 @@ private static IPAddress getIPfromHost(string p) if (hosts == null || hosts.Length == 0) { - throw new ArgumentException(string.Format("Host not found: {0}", p)); + throw new ArgumentException($"Host not found: {p}"); } return hosts[0]; } catch { - throw new ArgumentException(string.Format("Host not found: {0}", p)); + throw new ArgumentException($"Host not found: {p}"); } } diff --git a/src/SIPSorcery/sys/TypeExtensions.cs b/src/SIPSorcery/sys/TypeExtensions.cs index 730b0d04f..69d24596c 100644 --- a/src/SIPSorcery/sys/TypeExtensions.cs +++ b/src/SIPSorcery/sys/TypeExtensions.cs @@ -55,7 +55,7 @@ public static class TypeExtensions /// public static bool IsNullOrBlank(this string s) { - if (s == null || s.Trim(WhiteSpaceChars).Length == 0) + if (s == null || s.AsSpan().Trim(WhiteSpaceChars).Length == 0) { return true; } @@ -65,7 +65,7 @@ public static bool IsNullOrBlank(this string s) public static bool NotNullOrBlank(this string s) { - if (s == null || s.Trim(WhiteSpaceChars).Length == 0) + if (s == null || s.AsSpan().Trim(WhiteSpaceChars).Length == 0) { return false; } @@ -206,13 +206,11 @@ public static byte[] ParseHexStr(string hexStr) return buffer.ToArray(); } - //#if NET472 || NETSTANDARD2_0 public static void Deconstruct(this KeyValuePair tuple, out T1 key, out T2 value) { key = tuple.Key; value = tuple.Value; } - //#endif public static bool IsPrivate(this IPAddress address) {