Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tab completion hinting slows down paste on Windows #56884

Open
WalterMadelim opened this issue Dec 22, 2024 · 9 comments · May be fixed by #56895
Open

tab completion hinting slows down paste on Windows #56884

WalterMadelim opened this issue Dec 22, 2024 · 9 comments · May be fixed by #56895
Labels
completions Tab and autocompletion in the repl REPL Julia's REPL (Read Eval Print Loop)

Comments

@WalterMadelim
Copy link

WalterMadelim commented Dec 22, 2024

I use win11. The text editor is VScode. I use the portable version of Julia release.
If a block of code is copied from a *.jl text file, and pasted to a julia REPL in VScode, then the code can be checked and executed.
This workflow worked well, until yesterday I decided to use the latest stable release of Julia, which is 1.11.2.

Then I found that the code refreshing speed is manifestly slowed, compared with the previous version (1.10.2).
Could you tell me the reason and ways to sort it out?

I really did an experiment to exhibit this difference. For a 100-line code block, If 1.10.2 is used, the finishing time of code checking is 1.87 seconds.
If 1.11.2 is used, the time is 10.55 seconds.

(in Julia REPL, after the code is pasted)
The code review process of 1.10.2 seems to be line-by-line and it is fast, which is pleasant.
But the code review process of 1.11.2 seems to be word-by-word and it is very slow, which is annoying.

I append the code block (it is an expression indeed, you can easily use another block instead) here for convenience

quote
    function one(cb_data, cb_where::Cint)
        jvcb_scalar(x) = JuMP.callback_value(cb_data, x)
        jvcb(x) = jvcb_scalar.(x)
        cb_where == Gurobi.GRB_CB_MIPSOL || return
        Gurobi.load_callback_variable_primal(cb_data, cb_where)
        o1po2, lbℶ1 = jvcb_scalar(o1) + jvcb_scalar(o2), jvcb_scalar(o3)
        u_, v_, x_, β1_ = jvcb(u), jvcb(v), jvcb(x), jvcb(β1)
        while true # must generate violating cut, or terminate
            iY = argmaxindY(u_, v_, x_, yM, β1_)
            ubℶ1 = ub_φ1(u_, v_, x_, yM, iY, β1_)
            β2, oℶ2 = get_β2_oℶ2(ℶ2, u_, v_, x_, yM[:, :, iY])
            Z = argmaxZ(u_, v_, x_, yM[:, :, iY], β2)
            Δ2_saturated = evalPush_Δ2(u_, v_, x_, yM, iY, Z, β2)
            cutSuccV[2] = true
            tryPush_ℶ2(Z, yM, iY, oℶ2, u_, v_, x_, β2)
            cutSuccV[1] = true
            ℶ1_saturated = tryPush_ℶ1(yM, iY, lbℶ1, u_, v_, x_, β1_)
            if ℶ1_saturated
                if Δ2_saturated && cutSuccV[2] == false
                    @info " ℶ2, ℶ1, Δ2 S⋅A⋅T, thus return without a violating cut"
                    return
                end
            else
                cutSuccV[1] || @error "ℶ1 is unupdated when it is unsaturated"
                ı = ℶ1CntV[1]
                ı += 1
                cut_expr = ℶ1["cn"][ı] + ip(ℶ1["pu"][ı], u) + ip(ℶ1["pv"][ı], v) + ip(ℶ1["px"][ı], x) + ip(ℶ1[""][ı], β1)
                JuMP.MOI.submit(ø, JuMP.MOI.LazyConstraint(cb_data), JuMP.@build_constraint(o3 >= cut_expr))
                ℶ1CntV[1] = ı
                return
            end
        end
    end
    function another(cb_data, cb_where::Cint)
        jvcb_scalar(x) = JuMP.callback_value(cb_data, x)
        jvcb(x) = jvcb_scalar.(x)
        cb_where == Gurobi.GRB_CB_MIPSOL || return
        Gurobi.load_callback_variable_primal(cb_data, cb_where)
        o1po2, lbℶ1 = jvcb_scalar(o1) + jvcb_scalar(o2), jvcb_scalar(o3)
        u_, v_, x_, β1_ = jvcb(u), jvcb(v), jvcb(x), jvcb(β1)
        while true # must generate violating cut, or terminate
            iY = argmaxindY(u_, v_, x_, yM, β1_)
            ubℶ1 = ub_φ1(u_, v_, x_, yM, iY, β1_)
            β2, oℶ2 = get_β2_oℶ2(ℶ2, u_, v_, x_, yM[:, :, iY])
            Z = argmaxZ(u_, v_, x_, yM[:, :, iY], β2)
            Δ2_saturated = evalPush_Δ2(u_, v_, x_, yM, iY, Z, β2)
            cutSuccV[2] = true
            tryPush_ℶ2(Z, yM, iY, oℶ2, u_, v_, x_, β2)
            cutSuccV[1] = true
            ℶ1_saturated = tryPush_ℶ1(yM, iY, lbℶ1, u_, v_, x_, β1_)
            if ℶ1_saturated
                if Δ2_saturated && cutSuccV[2] == false
                    @info " ℶ2, ℶ1, Δ2 S⋅A⋅T, thus return without a violating cut"
                    return
                end
            else
                cutSuccV[1] || @error "ℶ1 is unupdated when it is unsaturated"
                ı = ℶ1CntV[1]
                ı += 1
                cut_expr = ℶ1["cn"][ı] + ip(ℶ1["pu"][ı], u) + ip(ℶ1["pv"][ı], v) + ip(ℶ1["px"][ı], x) + ip(ℶ1[""][ı], β1)
                JuMP.MOI.submit(ø, JuMP.MOI.LazyConstraint(cb_data), JuMP.@build_constraint(o3 >= cut_expr))
                ℶ1CntV[1] = ı
                return
            end
        end
    end
    function yetanother(cb_data, cb_where::Cint)
        jvcb_scalar(x) = JuMP.callback_value(cb_data, x)
        jvcb(x) = jvcb_scalar.(x)
        cb_where == Gurobi.GRB_CB_MIPSOL || return
        Gurobi.load_callback_variable_primal(cb_data, cb_where)
        o1po2, lbℶ1 = jvcb_scalar(o1) + jvcb_scalar(o2), jvcb_scalar(o3)
        u_, v_, x_, β1_ = jvcb(u), jvcb(v), jvcb(x), jvcb(β1)
        while true # must generate violating cut, or terminate
            iY = argmaxindY(u_, v_, x_, yM, β1_)
            ubℶ1 = ub_φ1(u_, v_, x_, yM, iY, β1_)
            β2, oℶ2 = get_β2_oℶ2(ℶ2, u_, v_, x_, yM[:, :, iY])
            Z = argmaxZ(u_, v_, x_, yM[:, :, iY], β2)
            Δ2_saturated = evalPush_Δ2(u_, v_, x_, yM, iY, Z, β2)
            cutSuccV[2] = true
            tryPush_ℶ2(Z, yM, iY, oℶ2, u_, v_, x_, β2)
            cutSuccV[1] = true
            ℶ1_saturated = tryPush_ℶ1(yM, iY, lbℶ1, u_, v_, x_, β1_)
            if ℶ1_saturated
                if Δ2_saturated && cutSuccV[2] == false
                    @info " ℶ2, ℶ1, Δ2 S⋅A⋅T, thus return without a violating cut"
                    return
                end
            else
                cutSuccV[1] || @error "ℶ1 is unupdated when it is unsaturated"
                ı = ℶ1CntV[1]
                ı += 1
                cut_expr = ℶ1["cn"][ı] + ip(ℶ1["pu"][ı], u) + ip(ℶ1["pv"][ı], v) + ip(ℶ1["px"][ı], x) + ip(ℶ1[""][ı], β1)
                JuMP.MOI.submit(ø, JuMP.MOI.LazyConstraint(cb_data), JuMP.@build_constraint(o3 >= cut_expr))
                ℶ1CntV[1] = ı
                return
            end
        end
    end
end
@WalterMadelim
Copy link
Author

WalterMadelim commented Dec 22, 2024

Seems like that we should use this command

Base.active_repl.options.hint_tab_completes = false

But this command cannot be executed at startup.jl.
Is there anyway to ban this auto_complete? it takes too much pointless time.
I suggest that we revert to 1.10.2, What's your opinion? It is so uncomfortable to use.

PS just as uncomfortable as ios18, which removes the video review bar in its photos app, what a pity.

@KristofferC
Copy link
Member

My guess is that in windows the REPL see this as just entering characters quickly (since no bracket paste mode) and the tab complete suggestion will run after every character. This would indeed slow things down.

@WalterMadelim
Copy link
Author

WalterMadelim commented Dec 22, 2024

Maybe it's true for windows.

We really don't need this superfluous prompt. If I want to, I can press Tab handily.
Since copy-paste is a convenient workflow, I think we should speed up this process rather than hinder it.

By the way, is there any other method to speed up? Since I catch this problem today.

There is a saying: "I could have withstood darkness, if I had never seen brightness".

If I learn Julia from version 1.11.2, I would recognize this 10 seconds for 100 line of code as a normal speed. 💀

@LilithHafner
Copy link
Member

I tried to emulate this with pyautogui.write on linux. It was substantially slower than pasting on all Julia versions, but 1.11 was a similar speed to 1.10.

@IanButterworth
Copy link
Member

@WalterMadelim the instructions to disable tab complention hinting in startup.jl is here and here

if VERSION >= v"1.11.0-0"
  atreplinit() do repl
      repl.options.hint_tab_completes = false
  end
end

We need to figure out how to implement cancelling completion generation on the next keystroke. It's discussed here #55434 (comment)

@IanButterworth IanButterworth added REPL Julia's REPL (Read Eval Print Loop) completions Tab and autocompletion in the repl labels Dec 22, 2024
@IanButterworth
Copy link
Member

Otherwise, is there any way to identify when stuff is being pasted in in Windows, so we can disable hinting temporarily?

@WalterMadelim
Copy link
Author

@IanButterworth Thanks, it works.

@KristofferC
Copy link
Member

@IanButterworth, we could maybe piggy back on

# cancel auto-indent when next character is entered within this time frame :
auto_indent_time_threshold::Float64
which was created to solve a similar issue with copy paste in windows?

@IanButterworth
Copy link
Member

Can a windows user check the proposed fix here #56895

@IanButterworth IanButterworth changed the title the code refreshing speed after copy-paste in Julia REPL is greatly slowed, after updating Julia from 1.10.2 (2024-03-01) to 1.11.2 (2024-12-01) tab completion hinting slows down paste on Windows Dec 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
completions Tab and autocompletion in the repl REPL Julia's REPL (Read Eval Print Loop)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants