Previous Entry Share
Многопоточная качалка на Erlang
what_me
Ну вот, моя первая программа на эрланге. https://github.com/onokhov/erlang_web_crawler/

Язык занятный. Параллелить и устраивать межпроцессное общение просто. Но остальное писать неудобно, думаю, что просто с непривычки. И документацию я ещё не прочитал. Осилил только getting_started, описания модулей string, list, re, httpc и ещё некоторых.
Сторонние модули использовать не хотелось, поэтому то, что в штатных модулях не нашел, делал сам.

Сравнил по производительности с перловой качалкой, эрланговская получилась немного быстрее. За минуту с форума glav.su перловая вытянула 26МБ, а эрланговская 26,7МБ.

Хотелось бы критики по коду от людей эрланг знающих.

Update: Закоммитил правки по комментариям. Заменены паттерны, ++ заменен на [|], использованы list comprehensions.
Update 2: Отказ от prespawn. И правки по стилю
Update 3: Багфикс в receive_text_data/2. Правки по стилю
Tags: ,

  • 1
а вот замена тренарному оператору "?:" какая?

# Хочу выкинуть порт, если он совпадает с дефолтным для схемы
PortPart = ( Scheme eq 'http' &&  Port == 80 ) ? '' : Port;


Я накорябал
if_not_empty(Test, Result) -> % не хватает в эрланге тренарного оператора ? : 
    case Test of
        [] ->
            [];
        _ ->
            Result
    end.

filter_default_port({Scheme, Port}) ->
    case {Scheme, Port} of
        {http, 80} ->
            [];
        {https, 443} ->
            [];
        {ftp, 21} ->
            [];
        _ ->
            Port
    end.

PortPart = if_not_empty(filter_default_port({Scheme, Port}), ":" ++ integer_to_list(Port)).


Как это улучшить?

Edited at 2017-01-08 07:16 am (UTC)

обоснуйте утверждение

Ничего себе, как быстро журнал заморозили. А я на срачик рассчитывал.

ne nado! mochi trollej, oni razrushajut bazovoje doverije k ljudjam.

nu etot operator i v sishechke nuzhen odin raz v god, a v Erlange prosto nenuzhen, potomuchto v Erlange vyzov funkcii sam po sebe delajet vetvlenije.

i da "case" eto vcelom edinstvennaja (ona zhe jestestvennaja, a znachit xoroshaja) zamena ternarnomu operatoru. no ty uchti chto "case" eto prosto takaja forma zapisi dlja mnogogolovoj funkcii, na samom dele "case" IDENTICHEN opredeleniju funkcii s tolikimi golovami koliko "entry" v "case".

jesli u tebja "umolchabeljnyj" argument, to pishi:

foo(A, [], C) -> foo(A, "default value", C);
foo(A, B, C) -> do_something.

ili

foo(A, B) -> foo(A, B, "default value").
foo(A, B, C) -> do_something.

sobstvenno dlinnaja chereda takix golov ochenj krasivo i kompaktno opisyvajet chto mozhno umolchatj i kak, i ty potom k voprosu "neopredeljonnosti" ne vratish sja v tele funkcii, telo rabotajet v PREZUMPCII chto golova opredelila vse nuzhnyje nam argumenty.

a jesli u tebja takaja faljshivaja neopredeljonnostj vypolzajet v seredine koda, naprimer ty razparsil kakoj-to kusok gavna i tam ne xvatalo chego-to, togda pishi:

A = case A_raw of [] -> "default value"; _ -> A_raw end

nichego zazornogo, ili nechitajemogo tut net.


a filter_default_port() nado perepisatj! objazateljno!
funkcija kotoraja sostoit iz odnogo "case" ne imejet prava!

filter_default_port({http, 80}) -> [];
filter_default_port({https, 443}) -> [];
filter_default_port({ftp, 21}) -> [];
filter_default_port({_, Port}) -> Port.

nu i kortezh v etom sluchaje sozdavatj ne nado, mozhno zhe napisatj foo(A,B) vmesto foo({A,B})

Ага, спасибо. Фильтр, кстати, я именно так и переписал в последнем коммите.

  • 1
?

Log in

No account? Create an account