[erlang-questions] Coming Back (maybe improving lists:reverse/1)

Ivan Carmenates Garcia <>
Thu Oct 8 02:20:29 CEST 2015


For example this is one of the algorithms, I optimize it as well as I could:

 

Considering here that the order of the fields is very important!.

 

%% -------------------------------------------------------------------

%% @private

%% @doc

%% Parses the specified list of full fields into a string containing

%% all full fields separated my comma.

%% example:

%% <pre>

%%   parse_full_fields([{users, '*'}, name, {roles, [id, level]},

%%       {users, name, alias}], fun get_postgres_operator/2) ->

%%       {"users.'*',name,roles.id,roles.level,users.name AS alias",

%%           [users, roles]}.

%% </pre>

%% Returns `{[], []}' if called with `[]'.

%% @throws {error, invalid_return_fields_spec, InvalidForm :: any()}

%% @end

%% -------------------------------------------------------------------

-spec parse_return_full_fields(FullFieldsSpecs, Separator, OperatorFinder)
-> Str when

    FullFieldsSpecs :: proplists:proplist(),

    Separator :: string(),

    OperatorFinder :: fun(),

    Str :: string().

parse_return_full_fields(FullFieldsSpecs, Separator, OperatorFinder) ->

    {ParsedFields, TableNames} =

        parse_full_fields2(FullFieldsSpecs, [], [], OperatorFinder),

    {string:join(lists:reverse(ParsedFields), Separator), TableNames}.

 

%% @private

%% base case.

parse_full_fields2([], ParsedKeys, TableNames, _) ->

    {ParsedKeys, TableNames};

%% {table_name(), [field_name(), ...]}.

parse_full_fields2([{TableName, [_FieldName | _] = FieldNames} | Rest],

    ParsedKeys, TableNames, OperatorFinder) ->

    %% -->

    NewParsedKeys =

        parse_field_names(FieldNames, [], atom_to_list(TableName),
OperatorFinder),

%%         lists:map(fun(FieldName) ->

%%             atom_to_list(TableName) ++ OperatorFinder('.', special_op)

%%                 ++ parse_field_name(FieldName, OperatorFinder)

%%         end, FieldNames),

    parse_full_fields2(Rest,

        NewParsedKeys ++ ParsedKeys, [TableName | TableNames],
OperatorFinder);

 

%% {table_name(), field_name(), field_name_alias()}.

parse_full_fields2([{TableName, FieldName, Alias} | Rest],

    ParsedKeys, TableNames, OperatorFinder) when FieldName =/= '*' ->

    %% -->

    parse_full_fields2(Rest, [

            atom_to_list(TableName) ++ OperatorFinder('.', special_op)

            ++ parse_field_name(FieldName, OperatorFinder) ++

            " " ++ OperatorFinder('ALIAS', special_op) ++ " " ++
atom_to_list(Alias)

        | ParsedKeys], [TableName | TableNames], OperatorFinder);

%% {table_name(), '*', field_name_alias()}. Throws an ERROR!.

parse_full_fields2([{_TableName, _FieldName, _Alias} = InvalidForm | _], _,
_, _) ->

    erlang:throw({error, {invalid_return_fields_spec, InvalidForm}});

%% {table_name(), field_name()}.

parse_full_fields2([{TableName, FieldName} | Rest],

    ParsedKeys, TableNames, OperatorFinder) ->

    %% -->

    parse_full_fields2(Rest,

        [atom_to_list(TableName) ++ OperatorFinder('.', special_op)

            ++ parse_field_name(FieldName, OperatorFinder) | ParsedKeys],

        [TableName | TableNames], OperatorFinder);

%% [field_name(), ...].

parse_full_fields2([FieldName | Rest],

    ParsedKeys, TableNames, OperatorFinder) when is_atom(FieldName) ->

    %% -->

    parse_full_fields2(Rest,

        [parse_field_name(FieldName, OperatorFinder) | ParsedKeys],
TableNames, OperatorFinder);

%% Throws an ERROR! if no valid form is provided.

parse_full_fields2(InvalidForm, _, _, _) ->

    erlang:throw({error, {invalid_return_fields_spec, InvalidForm}}).

 

%% @private

 

parse_field_name('*', OperatorFinder) ->

    OperatorFinder('*', special_op);

parse_field_name(FieldName, _OperatorFinder) ->

    atom_to_list(FieldName).

 

%% @private

parse_field_names([], ParsedFieldNames, _, _) ->

    ParsedFieldNames;

parse_field_names([FieldName | Rest],

    ParsedFieldNames, BaseTableName, OperatorFinder) when is_atom(FieldName)
->

    %% -- >

    parse_field_names(Rest, [

            BaseTableName ++ OperatorFinder('.', special_op)

            ++ parse_field_name(FieldName, OperatorFinder)

        | ParsedFieldNames], BaseTableName, OperatorFinder);

%% throws an ERROR! if no valid form is provided.

parse_field_names(InvalidForm, _, _, _) ->

    erlang:throw({error, {invalid_return_fields_spec, InvalidForm}}).

 

 

Cheers,

 

 

-----Original Message-----
From: 
[mailto:] On Behalf Of Ivan Carmenates
Garcia
Sent: Wednesday, October 7, 2015 8:11 PM
To: 'Richard A. O'Keefe'
Cc: 'Erlang Questions Mailing List'
Subject: Re: [erlang-questions] Coming Back (maybe improving
lists:reverse/1)

 

Yes that is so, but in my case, I cannot find a better way to improve it, I
did it as better could so, that's when Joes words give me pleasure. ;)

 

Regards,

Ivan (son of Gilberio).

 

 

-----Original Message-----

From: Richard A. O'Keefe [ <mailto:>
mailto:]

Sent: Wednesday, October 7, 2015 7:51 PM

To: Ivan Carmenates Garcia

Cc: Erik Søe Sørensen; Erlang Questions Mailing List

Subject: Re: [erlang-questions] Coming Back (maybe improving

lists:reverse/1)

 

 

On 8/10/2015, at 11:49 am, Ivan Carmenates Garcia <
<mailto:> >

wrote:

 

> Nice.

>  

> So in order of balance between memory and speed is the best ways as it

is?.

 

Ill-posed qwuestion.  No answer is possible until you specify best in *what

respect* for *what purpose*.

 

Doubly linked lists are said to have their uses, but any time I've been

tempted to use them, some other data structure has always turned out to be

much better.  There are actually several different ways to implement singly

linked lists (anyone else out there remember CDR-coding?) more than one of

which could be used for Erlang, so it's even harder to assign any meaning to

the question than you might think.

 

For example, I have a library that I've ported to several functional

programming languages providing unrolled lists.  For example,

 

    data URSL t

       = Cons4 t t t t (URSL t)

       | End3 t t t

       | End2 t t 

       | End1 t

       | End0

 

This takes 6 words for every 4 elements, an average of 1.5 words per

element.  (A doubly linked list would require at least twice as much.) On

the other hand, it's very bad at prepending a single element.  So unroll

from the _other_ end; that way you need one End but more than one Cons.  

 

> Okay, sounds good to me, also Joe was saying something that I like some

kind about algorithms optimizations, because I am a little bit hard about

it, but for example in this little framework I am doing for myself and the

community if they like of course there are parts in which maybe I think some

algorithms could be better but if it works and it does quite well, i.e. if

in my computer with one millions of iterations in one process this is

important because each user will have one process for its own, it take 21

seconds to perform and in a core i3 with 2 GB of single channel memory it

take 9 seconds, then in a real server with 64 cores and super memory it will

take none milliseconds to perform so, in the future machines will be better

each time and maybe we don’t have to be so extreme about performance.

 

This is extremely vague.  All I can say is

 

    Remember that the BIGGEST performance gains come

    from optimising at the HIGHEST level.

 

_______________________________________________

erlang-questions mailing list

 <mailto:> 

 <http://erlang.org/mailman/listinfo/erlang-questions>
http://erlang.org/mailman/listinfo/erlang-questions

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20151007/043efe39/attachment.html>


More information about the erlang-questions mailing list