elixir-editors / elixir-editors/vim-elixir

Indent Performance: string/comment lookups

Aperta
#407 13 commenti 0 reazioni 0 assegnatari Vedi su GitHub
enhancement HIGH-PRIORITY indent maybe-fixed?
Lingua principale
Ruby
Stelle
1.3k
Fork
154
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Descrizione

Given the following file:

```
defmodule Http do
defmacro __using__(_) do
quote do
use HTTPoison.Base

def get(url, headers \\ [], options \\ []) do
response(:get, url, "", headers, options)
end

def delete(url, headers \\ [], options \\ []) do
response(:delete, url, "", headers, options)
end

def post(url, body, headers \\ [], options \\ []) do
response(:post, url, body, headers, options)
end

def patch(url, body, headers \\ [], options \\ []) do
response(:patch, url, body, headers, options)
end

def response(method, url, body, headers \\ [], options \\ []) do
url = options.base_url <> url
log(method, :start, url, options)
start_time = now()

response = request(method, url, body, headers, options)

case response do
{:ok, response} ->
log(method, :finish, url, options, response, start_time)

{:error, response} ->
log(method, :error, url, options, response, start_time)
end

response
end

def process_request_options(%_{} = options) do
options
|> Map.from_struct()
|> Enum.into([])
|> process_request_options()
end

def process_request_options(options) do
[
timeout: 10_000,
recv_timeout: 15_000,
hackney: [pool: :http_default_pool]
]
|> Keyword.merge(options)
end

def process_request_body(body) when is_map(body), do: Poison.encode!(body)
def process_request_body(body) when is_binary(body), do: body

def process_response_body(body) do
case Poison.Parser.parse(body) do
{:ok, parsed_body} -> parsed_body
{:error, _} -> body
end
end

def process_request_headers(headers) do
headers
end

defp now(), do: DateTime.utc_now() |> DateTime.to_unix(:millisecond)

defp log(request_method, at, path, options, response \\ nil, started_at \\ nil) do
data = %{
api_request: true,
at: at,
host: options.base_url,
request_id: options.request_id,
url: path,
method: request_method,
path: options.generic_path,
elapsed: started_at && now() - started_at
# status: response && response.status_code,
# reason: response && response.reason
}

# remove keys with falsy values
data = for {key, value} <- data, value, into: %{}, do: {key, value}

case response do
nil -> Plexy.Logger.debug(data)
%HTTPoison.Response{} -> Plexy.Logger.debug(data)
%HTTPoison.Error{} = error -> Plexy.Logger.error(data)
end
end
end
end
end
```

We get the following profiler output:

```
FUNCTIONS SORTED ON SELF TIME
count total (s) self (s) function
9466 10.457848 77_is_string_or_comment()
312 11.036247 1.915420 elixir#indent#handle_inside_nested_construct()
8828 9.363995 0.120360 elixir#indent#searchpair_back_skip()
1522 1.123686 0.106535 77_ends_with()
384 13.163921 0.071142 elixir#indent#indent()
52 0.205268 0.054884 elixir#indent#handle_inside_generic_block()
382 0.210430 0.053353 elixir#indent#handle_starts_with_end()
2542 0.096197 0.048705 77_starts_with()
398 61.177775 0.024607 77_get_base_indent()
326 0.164678 0.021031 elixir#indent#handle_starts_with_close_bracket()
4644 0.017567 77_debug()
312 0.018112 0.006850 elixir#indent#handle_starts_with_binary_operator()
334 0.020190 0.006785 elixir#indent#handle_starts_with_pipe()
358 0.013070 0.005970 elixir#indent#handle_starts_with_mid_or_end_block_keyword()
358 0.087979 0.005809 elixir#indent#handle_following_trailing_do()
334 0.037895 0.003777 elixir#indent#handle_following_trailing_binary_operator()
230 0.003508 elixir#indent#handle_starts_with_comment()
8 0.003288 77_find_last_pos()
384 13.166979 0.003058 elixir#indent()
1274 0.002925 77_keyword()
```

The clear culprit is delegating to the syntax engine over and over. One thought - can we filter out all of the strings in a preprocessing step perhaps? That would surely be cheaper than checking them over and over

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

Direzione di ricerca

Inizia da elixir#indent#indent() e elixir#indent#handle_inside_nested_construct(), quindi esegui il profiling delle chiamate ripetute a 77_is_string_or_comment() e elixir#indent#searchpair_back_skip(). Confronta il comportamento dell'indentazione prima e dopo qualsiasi preelaborazione o riduzione delle ricerche; il lavoro è completato quando viene preservata l'indentazione corretta riducendo al contempo il costo delle ricerche ripetute di stringhe/commenti.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
elixir, vim
Ambito
performance, tooling
Tipo di issue
Refactoring
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
28/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.