@@ -73,6 +73,8 @@ for sz in (1, 4, 8, 16, 32, 64, 128, 256)
73
73
end
74
74
end
75
75
76
+ const SmallInlineStrings = Union{String1, String3, String7, String15}
77
+
76
78
# used to zero out n lower bytes of an inline string
77
79
clear_n_bytes (s, n) = Base. shl_int (Base. lshr_int (s, 8 * n), 8 * n)
78
80
_bswap (x:: T ) where {T <: InlineString } = T === InlineString1 ? x : Base. bswap_int (x)
@@ -595,10 +597,11 @@ end
595
597
end
596
598
597
599
const BaseStrs = Union{Char, String, SubString{String}}
598
- Base. string (a:: InlineString ) = String (a)
600
+ Base. string (a:: InlineString ) = a
599
601
Base. string (a:: InlineString... ) = _string (a... )
600
602
Base. string (a:: BaseStrs , b:: InlineString ) = _string (a, b)
601
603
Base. string (a:: BaseStrs , b:: BaseStrs , c:: InlineString ) = _string (a, b, c)
604
+
602
605
@inline function _string (a:: Union{BaseStrs, InlineString} ...)
603
606
n = 0
604
607
for v in a
@@ -616,6 +619,40 @@ Base.string(a::BaseStrs, b::BaseStrs, c::InlineString) = _string(a, b, c)
616
619
return out
617
620
end
618
621
622
+ # For more and/or bigger InlineStrings creating a `Base.String` is faster
623
+ const _SmallerInlineStrings = Union{InlineString1, InlineString3, InlineString7}
624
+ Base. string (a:: _SmallerInlineStrings , b:: _SmallerInlineStrings , c:: _SmallerInlineStrings ) =
625
+ _string (_string (a, b), c)
626
+ const _SmallestInlineStrings = Union{InlineString1, InlineString3}
627
+ Base. string (a:: _SmallestInlineStrings , b:: _SmallestInlineStrings , c:: _SmallestInlineStrings , d:: _SmallestInlineStrings ) =
628
+ _string (_string (_string (a, b), c), d)
629
+
630
+ # Only benefit from keeping the small-ish strings as InlineStrings
631
+ function _string (a:: Ta , b:: Tb ) where {Ta <: SmallInlineStrings , Tb <: SmallInlineStrings }
632
+ T = summed_type (Ta, Tb)
633
+ lb_a = Int (! isa (a, InlineString1)) # no "length byte" to remove if InlineString1
634
+ lb_b = Int (! isa (b, InlineString1))
635
+ len_a = sizeof (a)
636
+ len_b = sizeof (b)
637
+ # Remove length byte (lshr), grow to new size (zext), move chars forward (shl).
638
+ a2 = Base. shl_int (Base. zext_int (T, Base. lshr_int (a, 8 * lb_a)), 8 * (sizeof (T) - sizeof (Ta) + lb_a))
639
+ b2 = Base. shl_int (Base. zext_int (T, Base. lshr_int (b, 8 * lb_b)), 8 * (sizeof (T) - sizeof (Tb) + lb_b - len_a))
640
+ lb = _oftype (T, len_a + len_b) # new length byte
641
+ return Base. or_int (Base. or_int (a2, b2), lb)
642
+ end
643
+
644
+ summed_type (:: Type{InlineString1} , :: Type{InlineString1} ) = InlineString3
645
+ summed_type (:: Type{InlineString3} , :: Type{InlineString1} ) = InlineString7
646
+ summed_type (:: Type{InlineString3} , :: Type{InlineString3} ) = InlineString7
647
+ summed_type (:: Type{InlineString7} , :: Type{InlineString1} ) = InlineString15
648
+ summed_type (:: Type{InlineString7} , :: Type{InlineString3} ) = InlineString15
649
+ summed_type (:: Type{InlineString7} , :: Type{InlineString7} ) = InlineString15
650
+ summed_type (:: Type{InlineString15} , :: Type{InlineString1} ) = InlineString31
651
+ summed_type (:: Type{InlineString15} , :: Type{InlineString3} ) = InlineString31
652
+ summed_type (:: Type{InlineString15} , :: Type{InlineString7} ) = InlineString31
653
+ summed_type (:: Type{InlineString15} , :: Type{InlineString15} ) = InlineString31
654
+ summed_type (a:: Type{<:SmallInlineStrings} , b:: Type{<:SmallInlineStrings} ) = summed_type (b, a)
655
+
619
656
function Base. repeat (x:: T , r:: Integer ) where {T <: InlineString }
620
657
r < 0 && throw (ArgumentError (" can't repeat a string $r times" ))
621
658
r == 0 && return " "
886
923
# # InlineString sorting
887
924
using Base. Sort, Base. Order
888
925
889
- # Only small-ish InlineStrings benefit from RadixSort algorithm
890
- const SmallInlineStrings = Union{String1, String3, String7, String15}
891
-
892
926
# And under certain thresholds, MergeSort is faster than RadixSort, even for small InlineStrings
893
927
const MergeSortThresholds = Dict (
894
928
1 => 2 ^ 5 ,
@@ -900,6 +934,7 @@ const MergeSortThresholds = Dict(
900
934
struct InlineStringSortAlg <: Algorithm end
901
935
const InlineStringSort = InlineStringSortAlg ()
902
936
937
+ # Only small-ish InlineStrings benefit from RadixSort algorithm
903
938
Base. Sort. defalg (:: AbstractArray{<:Union{SmallInlineStrings, Missing}} ) = InlineStringSort
904
939
905
940
struct Radix
0 commit comments