Верно ли, что Deedle / Series медленнее по сравнению со списком? - PullRequest
0 голосов
/ 22 ноября 2018

Я работаю над приложением, интенсивно использующим данные, и не уверен, стоит ли мне использовать Series./DataFrame.Это кажется очень интересным, но выглядит также намного медленнее, чем эквивалент, сделанный со списком ... но я не могу использовать Серию должным образом при фильтрации.Пожалуйста, дайте мне знать, что вы думаете.

Спасибо

type TSPoint<'a> =
 {
    Date : System.DateTime
    Value : 'a            
 }

type TimeSerie<'a> = TSPoint<'a> list

let sd = System.DateTime(1950, 2, 1)
let tsd =[1..100000] |> List.map (fun x -> sd.AddDays(float x))

// creating a List of TSPoint
let tsList = tsd |> List.map (fun x -> {Date = x ; Value = 1.}) 
// creating the same as a serie
let tsSeries = Series(tsd , [1..100000] |> List.map (fun _ -> 1.))

// function to "randomise" the list of dates
let shuffleG xs = xs |> List.sortBy (fun _ -> Guid.NewGuid())

// new date list to search within out tsList and tsSeries
let d = tsd |> shuffleG |> List.take 1000

// Filter
d |> List.map (fun x -> (tsList |> List.filter (fun y -> y.Date = x)))
d |> List.map (fun x -> (tsSeries |> Series.filter (fun key _ -> key = x)))

Вот что я получаю:

Список -> Реальный: 00: 00: 04.780, CPU: 00: 00: 04.508, GC gen0: 917, gen1: 2, gen2: 1

Серия -> Реальная: 00: 00: 54.386, CPU: 00: 00: 49.311, GC gen0: 944, gen1: 7gen2: 3

1 Ответ

0 голосов
/ 22 ноября 2018

Как правило, ряды Deedle и фреймы данных имеют некоторые дополнительные издержки по сравнению с написанием кода, созданного вручную, с использованием любой наиболее эффективной структуры данных для данной проблемы.Накладные расходы малы для некоторых операций и больше для некоторых операций, поэтому они зависят от того, что вы хотите сделать, и от того, как вы используете Deedle.

Если вы используете Deedle так, как это было задумано,тогда вы получите хорошую производительность, но если вы выполните большое количество операций, которые не особенно эффективны, вы можете получить плохую производительность.

В вашем конкретном случае вы запускаете Series.filter на 1000Создание серии и создание новой серии (что и происходит здесь за кулисами) имеет некоторые накладные расходы.

Однако, на самом деле ваш код делает то, что вы используете Series.filter, чтобы найти значение с определенным ключом,Для этого Deedle предоставляет операцию поиска на основе ключей (и это одна из вещей, для которой она была оптимизирована).

Если переписать код следующим образом, вы получите гораздо лучшую производительность с Deedle, чем со списком:

d |> List.map (fun x -> tsSeries.[x])
// 0.001 seconds

d |> List.map (fun x -> (tsSeries |> Series.filter (fun key _ -> key = x)))
// 3.46 seconds

d |> List.map (fun x -> (tsList |> List.filter (fun y -> y.Date = x)))
// 40.5 seconds
...