From e9895250b199774af99a517ded86ffc009c02504 Mon Sep 17 00:00:00 2001 From: t11s Date: Fri, 30 Dec 2022 16:09:43 -0800 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20Optimize=20toString(int256?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Vectorized <5889274+Vectorized@users.noreply.github.com> --- .gas-snapshot | 8 ++++---- lib/ds-test | 2 +- src/utils/LibString.sol | 19 +++++++++++++++++-- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/.gas-snapshot b/.gas-snapshot index 641515ba..c4c5c840 100644 --- a/.gas-snapshot +++ b/.gas-snapshot @@ -279,12 +279,12 @@ FixedPointMathLibTest:testSqrt(uint256) (runs: 256, μ: 997, ~: 1013) FixedPointMathLibTest:testSqrtBack(uint256) (runs: 256, μ: 15210, ~: 340) FixedPointMathLibTest:testSqrtBackHashed(uint256) (runs: 256, μ: 59066, ~: 59500) FixedPointMathLibTest:testSqrtBackHashedSingle() (gas: 58937) -LibStringTest:testDifferentiallyFuzzToString(uint256,bytes) (runs: 256, μ: 20875, ~: 8988) -LibStringTest:testDifferentiallyFuzzToStringInt(int256,bytes) (runs: 256, μ: 20129, ~: 8360) +LibStringTest:testDifferentiallyFuzzToString(uint256,bytes) (runs: 256, μ: 20892, ~: 8988) +LibStringTest:testDifferentiallyFuzzToStringInt(int256,bytes) (runs: 256, μ: 20081, ~: 8356) LibStringTest:testToString() (gas: 10069) LibStringTest:testToStringDirty() (gas: 8145) -LibStringTest:testToStringIntNegative() (gas: 11096) -LibStringTest:testToStringIntPositive() (gas: 10509) +LibStringTest:testToStringIntNegative() (gas: 9634) +LibStringTest:testToStringIntPositive() (gas: 10481) LibStringTest:testToStringOverwrite() (gas: 506) MerkleProofLibTest:testValidProofSupplied() (gas: 2153) MerkleProofLibTest:testVerifyEmptyMerkleProofSuppliedLeafAndRootDifferent() (gas: 1458) diff --git a/lib/ds-test b/lib/ds-test index 9310e879..cd98eff2 160000 --- a/lib/ds-test +++ b/lib/ds-test @@ -1 +1 @@ -Subproject commit 9310e879db8ba3ea6d5c6489a579118fd264a3f5 +Subproject commit cd98eff28324bfac652e63a239a60632a761790b diff --git a/src/utils/LibString.sol b/src/utils/LibString.sol index b0576b9d..97c89e0b 100644 --- a/src/utils/LibString.sol +++ b/src/utils/LibString.sol @@ -5,9 +5,24 @@ pragma solidity >=0.8.0; /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/LibString.sol) /// @author Modified from Solady (https://github.com/Vectorized/solady/blob/main/src/utils/LibString.sol) library LibString { - function toString(int256 value) internal pure returns (string memory) { + function toString(int256 value) internal pure returns (string memory str) { + if (value >= 0) return toString(uint256(value)); + unchecked { - return value >= 0 ? toString(uint256(value)) : string(abi.encodePacked("-", toString(uint256(-value)))); + str = toString(uint256(-value)); + + /// @solidity memory-safe-assembly + assembly { + // Note: This is only safe because we over-allocate memory + // and write the string from right to left in toString(uint256), + // and thus can be sure that sub(str, 1) is an unused memory location. + + let length := mload(str) // Load the string length. + // Put the - character at the start of the string contents. + mstore(str, 45) // 45 is the ASCII code for the - character. + str := sub(str, 1) // Move back the string pointer by a byte. + mstore(str, add(length, 1)) // Update the string length. + } } }