# Why is \[x\]or (a function call) so long/slow (not inlined)?

**URL:** https://discourse.julialang.org/t/why-is-x-or-a-function-call-so-long-slow-not-inlined/1264
**Category:** Offtopic
**Created:** [January 3, 2017, 6:25pm UTC](https://discourse.julialang.org/t/why-is-x-or-a-function-call-so-long-slow-not-inlined/1264 "2017-01-03T18:25:24Z")
**Posts on this page:** 1
**Showing post:** 21

<div class="post-metadata">

### Author: ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)
#### Post date: [January 4, 2017, 8:38pm UTC](https://discourse.julialang.org/t/why-is-x-or-a-function-call-so-long-slow-not-inlined/1264/21 "2017-01-04T20:38:27Z")

</div>

> [@jameson](#):
>
> the end of a function isn’t defined on all platforms [interesting…]
> 
> if that sounds like your cup of tea, PRs for better heuristics

My between functions, could be a PR for Base (but shouldn’t be needed… maybe non-exported building blocks for codegen?):

```julia
julia> between_arbitrary(from, op, to)=op(from, to) #do they violate coding standard with op (or in_val) in the middle?

julia> between_inclusive(from, in_val, to)=between_arbitrary(from, <=, in_val) & between_arbitrary(in_val, <=, to)

```

They simplify:

`new_uppercase(c::Char) = begin test1='a' <= c; test2=c <= 'z'; return test1&test2 ? Char(xor(UInt32(c), 0x20)) : Char(ccall(:utf8proc_toupper, UInt32, (UInt32,), c)) end`

to:

`new_uppercase(c::Char) = !between_inclusive('a', c, 'z') ? Char(ccall(:utf8proc_toupper, UInt32, (UInt32,), c)) : Char(xor(UInt32(c), 0x20))`

that assembly code, has one jump (one cmpl and ja each), not two jumps and compares as with straightforward (‘a’ \<= c \<= ‘z’).

[I don’t like that c ? “then” : “else”, considers the else, more likely; I fixed with !c and reversing. Both have as many jumps.]

Same applies to:

[Still frustrated to not see the 5x speedup that I timed.]

```julia
julia> new_uppercase_for_now_only_for_ascii(c::Char) = Char(xor(UInt32(c), between_inclusive('a', c, 'z') << 5))

julia> new_uppercase_for_now_only_for_ascii(c::Char) = Char(xor(UInt32(c), ('a' <= c <= 'z') << 5))

```

```julia
c = map(Char, rand(32:127, 5000000)); # note, not, that would work (getting to also run fast): c = rand(Char, 5000000);

julia> @time map(new_uppercase_for_now_only_for_ascii, c);
First run: 0.045256 seconds (8 allocations: 19.074 MB)
..
julia> @time map(new_uppercase_for_now_only_for_ascii, c);
  0.017182 seconds (8 allocations: 19.074 MB)

vs.

julia> @time map(new_uppercase, c);
  0.079274 seconds (8 allocations: 19.074 MB)

```

“Off-topic”:

> [@StefanKarpinski](#):
>
> what’s a nice word for “absurd”?

Absurd is a nice word. I might disagree about it’s use here. I was going to let this drop; as I said, not important, at the bottom of the list of my concerns with the code here.

> [@StefanKarpinski](#):
>
> _is_ part of the assembly generated for the function in question.

yes, for x86, no for “LLVM assembly language”

> [@StefanKarpinski](#):
>
> could spend a few minutes StackOverflow and figure it out.

I should have remembered, or just done that.

---

_[View the full topic](https://discourse.julialang.org/t/why-is-x-or-a-function-call-so-long-slow-not-inlined/1264)._
