Reputation: 3295
I have a dataset which contains more than 50k rows. I decided to take average of the first fifty values, then second fifty values and so on (so that I will get half of the Dataset with average of 50 value groups).
Here is my code:
var Rate = (from dr in ds.Tables[0].AsEnumerable()
select new
{
rate = dr.Field<double>(columnName)
}.rate).ToList();
if (Rate.Count > 50)
{
var avg = Rate.CheckRateValue();
}
And here is the code for my extension method:
public static IEnumerable<double> CheckRateValue(this IEnumerable<double> values)
{
int i = 1;
int j = 0;
for (; i < values.Count(); )
{
yield return values.Skip(j * 2).Take(2).Average();
i = i + 2;
j++;
}
}
Problem : It works fine but it's slow. Does anyone have any suggestions on how to speed it up?
Upvotes: 0
Views: 246
Reputation: 3295
By using row_number() i solved it.
declare @Skip int = 20
declare @Take int = 10
select SomeColumn
from (
select SomeColumn,
row_number() over(order by SomeColumnToOrderBy) as rn
from YourTable
) T
where rn > @Skip and
rn <= @Skip + @Take
Upvotes: 0
Reputation: 110121
for { yield return values.Skip(j * 2).Take(2).Average(); }
Moving to the current page from the start in each loop iteration: that will be n^2. See also Schlemiel the painter.
You should enumerate values
once!
Upvotes: 0
Reputation: 30708
If you want to take items in count of fifty and average it (like take first 50 , average it, take next 50, average it, and so on), and get list of Averages, you can use MoreLinq.Batch
You can use
var result = list.Batch(50).Select(x=> x.Average());
Upvotes: 1
Reputation: 31394
Using the DataTable.Compute may be faster because you skip the iteration to create List<dobule>
.
double average = (double)ds.Tables[0].Compute("avg(columnName)", "");
The second parameter is a fitler expression so you could use it to do your skipping if the data in the table allows it.
Upvotes: 2
Reputation: 19646
Why would that be any faster than simply:
var average = dat.AsEnumerable().Average(dr => (double)dr["ColumnName"]);
In fact - this should probably be faster than the extra complexity of taking 50 at a time...
Upvotes: 0
Reputation: 26737
var yourList=yourList.Take(50).Aggregate((acc, cur) => acc + cur) / list.Count
Upvotes: 1