Skip to content

Commit

Permalink
improve performance for string indexing (JuliaLang#29796)
Browse files Browse the repository at this point in the history
  • Loading branch information
KristofferC authored Oct 27, 2018
1 parent 1717adb commit 1038233
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 12 deletions.
4 changes: 2 additions & 2 deletions base/strings/basic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ julia> first("∀ϵ≠0: ϵ²>0", 3)
"∀ϵ≠"
```
"""
first(s::AbstractString, n::Integer) = s[1:min(end, nextind(s, 0, n))]
first(s::AbstractString, n::Integer) = @inbounds s[1:min(end, nextind(s, 0, n))]

"""
last(s::AbstractString, n::Integer)
Expand All @@ -621,7 +621,7 @@ julia> last("∀ϵ≠0: ϵ²>0", 3)
"²>0"
```
"""
last(s::AbstractString, n::Integer) = s[max(1, prevind(s, ncodeunits(s)+1, n)):end]
last(s::AbstractString, n::Integer) = @inbounds s[max(1, prevind(s, ncodeunits(s)+1, n)):end]

"""
reverseind(v, i)
Expand Down
17 changes: 7 additions & 10 deletions base/strings/string.jl
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,10 @@ typemin(::String) = typemin(String)

## thisind, nextind ##

thisind(s::String, i::Int) = _thisind_str(s, i)
Base.@propagate_inbounds thisind(s::String, i::Int) = _thisind_str(s, i)

# s should be String or SubString{String}
function _thisind_str(s, i::Int)
@inline function _thisind_str(s, i::Int)
i == 0 && return 0
n = ncodeunits(s)
i == n + 1 && return i
Expand All @@ -128,10 +128,10 @@ function _thisind_str(s, i::Int)
return i
end

nextind(s::String, i::Int) = _nextind_str(s, i)
Base.@propagate_inbounds nextind(s::String, i::Int) = _nextind_str(s, i)

# s should be String or SubString{String}
function _nextind_str(s, i::Int)
@inline function _nextind_str(s, i::Int)
i == 0 && return 1
n = ncodeunits(s)
@boundscheck between(i, 1, n) || throw(BoundsError(s, i))
Expand Down Expand Up @@ -237,7 +237,7 @@ end

getindex(s::String, r::UnitRange{<:Integer}) = s[Int(first(r)):Int(last(r))]

function getindex(s::String, r::UnitRange{Int})
@inline function getindex(s::String, r::UnitRange{Int})
isempty(r) && return ""
i, j = first(r), last(r)
@boundscheck begin
Expand All @@ -248,14 +248,11 @@ function getindex(s::String, r::UnitRange{Int})
j = nextind(s, j) - 1
n = j - i + 1
ss = _string_n(n)
p = pointer(ss)
for k = 1:n
unsafe_store!(p, codeunit(s, i + k - 1), k)
end
unsafe_copyto!(pointer(ss), pointer(s, i), n)
return ss
end

function length(s::String, i::Int, j::Int)
@inline function length(s::String, i::Int, j::Int)
@boundscheck begin
0 < i ncodeunits(s)+1 || throw(BoundsError(s, i))
0  j < ncodeunits(s)+1 || throw(BoundsError(s, j))
Expand Down

0 comments on commit 1038233

Please sign in to comment.