How to realize the following perl translating task in Julia?
#/user/bin/perl
my $string = ‘The cat sat on the mat’;
$string =~ tr/ao/oL/;
print “$string\n”;
#-------------------------
The cot sot Ln the mot
How to realize the following perl translating task in Julia?
#/user/bin/perl
my $string = ‘The cat sat on the mat’;
$string =~ tr/ao/oL/;
print “$string\n”;
#-------------------------
The cot sot Ln the mot
please use docs
https://docs.julialang.org/en/v1/base/strings/#Base.replace-Tuple{AbstractString,Pair}
which one ?
function tr(s::String,target::String,sub::String)
return Base.replace(s,target => sub)
end
mystring = "The cat sat on the mat"
mystring = tr(mystring,"at","ot")
println(mystring)
$ julia zzz.jl
The cot sot on the mot
It doesn’t work properly. The request means every character changes ( ‘a’ to ‘o’ and ‘o’ to ‘L’) independently against the original string.
julia> function g(s, tar, rep)
@assert length(tar) == length(rep)
replace(collect(s), Dict(zip(tar,rep))...) |> join
end
g (generic function with 1 method)
julia> g("The cat sat on the mat", "ao", "oL")
"The cot sot Ln the mot"
Quite smart solution.
but it costs 0.335752 seconds for 100000 loops. In contrast, Perl costs only 0.015 seconds.
You never told us that performance is a requirement.
Also, how did you get those timings? Make sure that you don’t benchmark in global scope.
@time begin
end
in global scope 0.335752 seconds
only for loops (excluding definition of function) 0.199178 seconds
try this
# Implement Perl tr function
function perl_tr(s::AbstractString, target::AbstractString, rep::AbstractString)
@assert length(target) == length(rep)
Base.replace(collect(s), Dict(zip(target,rep))...) |> join
end
let
mystring = "The cat sat on the mat"
mystring = perl_tr(mystring,"ao","oL")
println(mystring)
end
typecasting it to AbstractString could make it faster.
so, don’t to that!
This doesn’t type cast anything. Generally, explicit types in function signatures don’t matter for performance.
pretty sure the cost is in zip
and dict
, maybe just do a for loop.
This doesn’t type cast anything. Generally, explicit types in function signatures don’t matter for performance.
Doesn’t the compiler only generate code for AbstractString and for nothing else? So less code equals better performance.
No. It always specializes on the actual runtime types. Independent of the function signature. Explicit types only have the effect of a filter: don’t except anything but only subtypes of AbstractStrings
.
To be convenient for test, the Perl script attached here.
#!/usr/bin/perl
use strict;
use warnings;
my $i=100000;
my $start=times;
while ($i>1) {
my $string = ‘The cat sat on the mat’;
$string =~ tr/ao/oL/;
print “$string\n”;
$i–;
}
print times-$start," seconds\n";
You should comment out print “$string\n”; unless you want IO to be part of your benchmark.
can you please wrap your code with ``` for readability?
I wonder why there is no multi-pair version of replace
for strings. Anyways, the straightforward
function h(s)
snew = replace(s, 'o'=>'L')
return replace(snew, 'a'=>'o')
end
is already ~3x faster than the other Julia implementation in this thread:
using BenchmarkTools
function g(s, tar, rep)
@assert length(tar) == length(rep)
replace(collect(s), Dict(zip(tar,rep))...) |> join
end
function h(s)
snew = replace(s, 'o'=>'L')
return replace(snew, 'a'=>'o')
end
@btime g("The cat sat on the mat", "ao", "oL"); # 1.660 μs
@btime h("The cat sat on the mat"); # 527.368 ns
Running your perl script (after removing the print statements), I get: 15-31 ms
which is much slower. I don’t know if the perl benchmark is any good (I don’t know how to properly benchmark in perl). But taking it for what it is, the Julia implementation h
is more than 2500x faster.