%%%------------------------------------------------------------------- %%% File : get_fields.erl %%% Author : Jay Nelson %%% Description : %%% Benchmark for stream_extract_nth/3 performance. %%% %%% Created : 25 Jun 2005 by Jay Nelson %%%------------------------------------------------------------------- -module(get_fields). %% API -export([ sampleRecord/1, setOfRecords/1, time/2, test/4, convert_db_to_list/2, slow_collect/3, normal_collect/3, fast_collect/3, fastest_collect/3 ]). %%==================================================================== %% Tests %%==================================================================== sampleRecord(Num) -> <<"This is record #", Num:32/integer>>. setOfRecords(Count) -> RecNums = lists:seq(1, Count), concat_binary([sampleRecord(Num) || Num <- RecNums]). time(Type=slow, _Size=small) -> Bin = setOfRecords(25), timer:tc(get_fields, test, [Type, Bin, 7, 20]); time(Type=normal, _Size=small) -> Bin = setOfRecords(25), timer:tc(get_fields, test, [Type, Bin, 7, 20]); time(Type=fast, _Size=small) -> Bin = setOfRecords(25), timer:tc(get_fields, test, [Type, Bin, 7, 20]); time(Type=fastest, _Size=small) -> Bin = setOfRecords(25), timer:tc(get_fields, test, [Type, Bin, 7, 20]); time(Type=slow, _Size=large) -> Bin = setOfRecords(25000), timer:tc(get_fields, test, [Type, Bin, 7, 20]); time(Type=normal, _Size=large) -> Bin = setOfRecords(25000), timer:tc(get_fields, test, [Type, Bin, 7, 20]); time(Type=fast, _Size=large) -> Bin = setOfRecords(25000), timer:tc(get_fields, test, [Type, Bin, 7, 20]); time(Type=fastest, _Size=large) -> Bin = setOfRecords(25000), timer:tc(get_fields, test, [Type, Bin, 7, 20]); time(Type=slow, _Size=long) -> Bin = setOfRecords(25000), timer:tc(get_fields, test, [Type, Bin, 1700, 5000]); time(Type=normal, _Size=long) -> Bin = setOfRecords(25000), timer:tc(get_fields, test, [Type, Bin, 1700, 5000]); time(Type=fast, _Size=long) -> Bin = setOfRecords(25000), timer:tc(get_fields, test, [Type, Bin, 1700, 5000]); time(Type=fastest, _Size=long) -> Bin = setOfRecords(25000), timer:tc(get_fields, test, [Type, Bin, 1700, 5000]). test(slow, DB, FieldSize, RecSize) -> L = slow_collect(DB, FieldSize, RecSize), length(L); test(normal, DB, FieldSize, RecSize) -> L = normal_collect(DB, FieldSize, RecSize), length(L); test(fast, DB, FieldSize, RecSize) -> L = fast_collect(DB, FieldSize, RecSize), length(L); test(fastest, DB, FieldSize, RecSize) -> L = fastest_collect(DB, FieldSize, RecSize), length(L). %%==================================================================== %% API %%==================================================================== slow_collect(DB, FieldSize, RecSize) -> LDB = binary_to_list(DB), slow_collect(LDB, FieldSize, RecSize, []). slow_collect([], _FieldSize, _RecSize, FieldsCollected) -> lists:reverse(FieldsCollected); slow_collect(DB, FieldSize, RecSize, FieldsCollected) -> ThisField = lists:sublist(DB, 1, FieldSize), Rest = lists:nthtail(RecSize, DB), slow_collect(Rest, FieldSize, RecSize, [list_to_binary(ThisField) | FieldsCollected]). normal_collect(DB, FieldSize, RecSize) -> LDB = convert_db_to_list(DB, RecSize), normal_collect1(LDB, FieldSize, []). normal_collect1([], _FieldSize, FieldsCollected) -> lists:reverse(FieldsCollected); normal_collect1([ThisRec | Rest], FieldSize, FieldsCollected) -> <> = ThisRec, normal_collect1(Rest, FieldSize, [ThisField | FieldsCollected]). fast_collect(DB, FieldSize, RecSize) -> fast_collect(DB, FieldSize, RecSize, 0, []). fast_collect(DB, _FieldSize, _Length, Pos, FieldsCollected) when Pos >= size(DB) -> lists:reverse(FieldsCollected); fast_collect(DB, FieldSize, Length, Pos, FieldsCollected) -> << _Skip:Pos/binary, ThisField:FieldSize/binary, _More/binary>> = DB, fast_collect(DB, FieldSize, Length, Pos + Length, [ThisField | FieldsCollected]). fastest_collect(DB, ExtractSize, RecSize) -> stream_extract_nth(DB, ExtractSize, RecSize). %%==================================================================== %% Internal functions %%==================================================================== convert_db_to_list(DB, Length) -> convert_db_to_list(DB, Length, 0, size(DB), []). convert_db_to_list(_DB, _Length, Pos, DBSize, RecsCollected) when Pos >= DBSize -> lists:reverse(RecsCollected); convert_db_to_list(DB, Length, Pos, DBSize, RecsCollected) -> <<_Skip:Pos/binary, Rec:Length/binary, _Rest/binary>> = DB, convert_db_to_list(DB, Length, Pos + Length, DBSize, [Rec | RecsCollected]).