每秒产生一条数据,如何在产生数据的同时高效的保存其最近x条数据的平均数

shsyzl007 2016-06-08 11:18:11
产生数据的同时怎么把最新的x条数据保存到list里面。比如把最新的10条数据保存到list10里面
 List<double> list10= new List<double>();
while (true)
{
int n = new Random().Next(100, 200);
Thread.Sleep(1000);
}
...全文
213 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
Poopaye 2016-06-09
  • 打赏
  • 举报
回复
45万次就吓死你了?在普通i3上大概0.1个毫秒
xuzuning 2016-06-09
  • 打赏
  • 举报
回复
没有你这样死算的,计算均值使用的是递推公式计算的 第 n 天 MAn = (C1 + C2 + C3 + ... + Cn) / N 第 n+1 天 MAn+1 = (C2 + C3 + C4 + ... + Cn+1) / N = (MAn * N -C1 + Cn+1) / N 实际计算时并不做除法
     n
M =  ∑Ci
    i=1
即 Mn+1 = Mn - C1-n + Cn+1 缓存次序列,使用时再做除法 由于历史数据不会再改变,你完全可以对数据做持久化保存 股软中都有用到 db2 或 sqlite 数据库的
shsyzl007 2016-06-09
  • 打赏
  • 举报
回复
现在快的不行不行滴,用户爽的不要不要滴~
shsyzl007 2016-06-09
  • 打赏
  • 举报
回复
上图以示膜拜
shsyzl007 2016-06-09
  • 打赏
  • 举报
回复
引用 14 楼 xuzuning 的回复:
你先检查一下你的数据 MA 是滑动平均值,只要有数据,就不会算错 比如 MA10,每十个数据就可算得一个,MA60,每60个数据就算得一个
大神,你功夫已经飞出地球冲向外太空了!~ 我的耗时1秒你的方法却是0毫秒。。什么叫天?这就叫天啊~
shsyzl007 2016-06-09
  • 打赏
  • 举报
回复
上面截图是通达信的,实际放大缩小过程响应都在1秒内。但我自己按照每个点都计算一次平均值耗时大概3秒。
shsyzl007 2016-06-09
  • 打赏
  • 举报
回复
再进一步,有兴趣的可用继续

以计算上证指数均线为例,计算量还是很大的
假设存在100个数字,每个数字求其最近60个数字的平均值,那就需要计算100*60=600次。9000个数字需求计算:9000*60=45万次。这仅是计算一个数字附近60的平均值,实际情况可能同时需要计算每个数字附近的5,10,20,30,60等平均值。这样计算量是非常大的,5,10,20这些数字是允许用户自定义的,所以没法提前保存。软件是怎么做到不卡顿的呢。。。
  • 打赏
  • 举报
回复
看不懂意思,为什么不是一产生就放进队列
xuzuning 2016-06-09
  • 打赏
  • 举报
回复
你先检查一下你的数据 MA 是滑动平均值,只要有数据,就不会算错 比如 MA10,每十个数据就可算得一个,MA60,每60个数据就算得一个
shsyzl007 2016-06-09
  • 打赏
  • 举报
回复
引用 11 楼 xuzuning 的回复:
哪里的结果不对?
前面的数据ma10,和ma60数据都是0.后面有数据了,ma10和ma60正常是3000多,可算出来的结果小于100
xuzuning 2016-06-09
  • 打赏
  • 举报
回复
我做了个测试,你可以参考一下
        static void Stock()
{
var d = File.ReadLines("HS.txt").ToList();
var stock = new List<string[]>();
var flag = new string[] {"\t\t"};
for (var i = 0; i < d.Count; i++)
{
if (i >= 2) stock.Add(d[i].Split(flag, StringSplitOptions.RemoveEmptyEntries));
}
DateTime time1 = DateTime.Now;
var ma10 = 0f;
var MA10 = new float[stock.Count];
for (var i = 0; i < stock.Count; i++)
{
var c = float.Parse(stock[i][4]);
ma10 += c;
if(i >= 10)
{
ma10 -= float.Parse(stock[i-10][4]);
MA10[i] = (float)Math.Round(ma10 / 10, 3);
}
}
var sss = (DateTime.Now - time1).TotalMilliseconds;

Console.WriteLine(stock.Count);
Console.WriteLine("{0} {1} {2}", sss, ma10, MA10[MA10.Length - 1]);

time1 = DateTime.Now;

sss = (DateTime.Now - time1).TotalMilliseconds;

var t = stock.Select(x => float.Parse(x[4])).Reverse().ToList();
var q10 = t.Select((x, Index) => t.GetRange(Index, Math.Min(10, t.Count-Index)).Average()).Reverse().ToList();
var q60 = t.Select((x, Index) => t.GetRange(Index, Math.Min(60, t.Count - Index)).Average()).Reverse().ToList();


Console.WriteLine(stock.Count);
Console.WriteLine("{0} {1} {2} {3}", sss, ma10, q10[q10.Count - 1], q60[q60.Count - 1]);
}

数据是从股软里粘出来的,两种算法看不出速度差异
xuzuning 2016-06-09
  • 打赏
  • 举报
回复
哪里的结果不对?
shsyzl007 2016-06-09
  • 打赏
  • 举报
回复
Stock[0]是最旧的,处理后把最新的数据放在最前面
 public static List<Pub.Stock> GetStockMA2(List<Pub.Stock> Stock,ref double tt)
        {
            int num = Stock.Count;
            var MA10 = new double[num];
            var MA60 = new double[num];
            var ma10 = 0d;
            var ma60 = 0d;
            DateTime time1 = DateTime.Now;
            List<Pub.Stock> lists = new List<Pub.Stock>();
            for (int i = Stock.Count - 1; i > 0; i--)
            {
                ma10 += Stock[i].Close;
                ma60 += Stock[i].Close;
                if (i == 9) MA10[i] = ma10 / 10;
                if (i == 59) MA60[i] = ma60 / 60;
                if (i > 9)
                {
                    ma10 -= Stock[i - 10].Close;
                    MA10[i] = ma10 / 10;
                }
                if (i > 59)
                {
                    ma60 -= Stock[i - 60].Close;
                    MA60[i] = ma60 / 60;
                }

                Pub.Stock stock2 = new Pub.Stock();
                stock2.code = Stock[i].code;
                stock2.tradedate = Stock[i].tradedate;
                stock2.Open = Stock[i].Open;
                stock2.Close = Stock[i].Close;
                stock2.High = Stock[i].High;
                stock2.Low = Stock[i].Low;
                stock2.MA10 = MA10[i];
                stock2.MA60 = MA60[i];
                lists.Add(stock2);
            }
            double sss = (DateTime.Now - time1).TotalMilliseconds;
            return lists;
        }
shsyzl007 2016-06-09
  • 打赏
  • 举报
回复
引用 8 楼 xuzuning 的回复:
int num = Stock.Count;
var MA10 = new float[num];
var MA60 = new fload[num];
var ma10 = 0f;
var ma60 = 0f;

for(vat i = 0; i < num; i++)
{
  ma10 += Stock[i].Close;
  ma60 += Stock[i].Close;
  if(i == 9) MA10[i] = ma10 / 10;
  if(i ==59) MA60[i] = ma60 / 60;
  if(i > 9)
  {
    ma10 -= Stock[i-10].Close;
    MA10 = ma10 / 10;
  }
  if(i > 59)
  {
    ma60 -= Stock[i-60].Close;
    MA60 = ma60 / 60;
  }
}
我说的是这个意思
大神,你的算法非常快啊,500条数据耗时0毫秒,我上面的代码耗时800毫秒。我把完整代码贴出来,你看看那里有问题呢。计算的结果是不对的。
xuzuning 2016-06-09
  • 打赏
  • 举报
回复
int num = Stock.Count;
var MA10 = new float[num];
var MA60 = new fload[num];
var ma10 = 0f;
var ma60 = 0f;

for(vat i = 0; i < num; i++)
{
  ma10 += Stock[i].Close;
  ma60 += Stock[i].Close;
  if(i == 9) MA10[i] = ma10 / 10;
  if(i ==59) MA60[i] = ma60 / 60;
  if(i > 9)
  {
    ma10 -= Stock[i-10].Close;
    MA10 = ma10 / 10;
  }
  if(i > 59)
  {
    ma60 -= Stock[i-60].Close;
    MA60 = ma60 / 60;
  }
}
我说的是这个意思
shsyzl007 2016-06-09
  • 打赏
  • 举报
回复
楼上看看那里有问题,实际计算2000条数据耗时就1秒+,同时处理几个品种蜗牛了
 /// <summary>
        /// 计算MA
        /// </summary>
        /// <param name="stock"></param>
        /// <returns></returns>
        public static List<Pub.Stock> GetStockMA(List<Pub.Stock> Stock)
        {
            DateTime time1 = DateTime.Now;
            List<Pub.Stock> lists = new List<Pub.Stock>();
            for (int i = Stock.Count - 1; i > 0; i--)
            {
                double MA10 = MAValue(Stock, 10, i);
                double MA60 = MAValue(Stock, 60, i);

                Pub.Stock stock2 = new Pub.Stock();
                stock2.code = Stock[i].code;
                stock2.tradedate = Stock[i].tradedate;
                stock2.Open = Stock[i].Open;
                stock2.Close = Stock[i].Close;
                stock2.High = Stock[i].High;
                stock2.Low = Stock[i].Low;
                stock2.MA10 = MA10;
                stock2.MA60 = MA60;
                lists.Add(stock2);
            }
            double sss = (DateTime.Now - time1).TotalMilliseconds;
            return lists;
        }

        /// <summary>
        /// 计算MA
        /// </summary>
        /// <param name="stock"></param>
        /// <param name="ma"></param>
        /// <returns></returns>
        static double MAValue(List<Pub.Stock> stock, int ma, int start)
        {
            double temp = 0;
            try
            {
                for (int i = start; i > start - ma; i--)
                {
                    temp += stock[i].Close;
                }
                temp = temp / ma;
                return Math.Round(temp, 2);
            }
            catch { return 0; }
        }
        
threenewbee 2016-06-08
  • 打赏
  • 举报
回复
Queue<int> q = new Queue<int>; q.Enqueue(当前值); if (q.Count() > n) q.Dequeue(); 平均值 int n = (int)q.Average();
 OpenGL-自主高性能三维GIS平台架构与实现/第二季:实现三维GIS球体+ 高程数据章节名称DEM基础1DEM基础知识1.介绍基本的DEM知识2.什么是DEM,作用是什么2DEM数据1.如何获取/ 传统测量/激光扫描/无人机测量/ 点云数据/ 倾斜摄影2.如何使用/局部小规模(栅格数据,图片/tif),3. 组织方式4. 根据使用目的不同,介绍多种优化方法3DEM图层的实现原理14DEM数据结构定义struct  V3U3N4顶点数据的生成和计算WGS84投影计算5wgs84 投影球体被切成一个个小圆弧,一共60个投影带,分别为01,02.........60WGS的最新版本为WGS 84(也称作WGS 1984、EPSG:4326),1984年定义、最后修订于2004年。接口定义坐标转换Wgs84 数据加载6瓦片编号计算生成算法1. 经纬度到大地坐标的转换2.大地坐标到经纬度坐标转换3. 根据经纬度获取瓦片编号框架重构7智能指针重构框架1. 基类定义(所有的类继承自基类),基类派生自 std::enbale_shared_from_this2. 实现智能指针的动态转换接口3. 实现向下转换4. 已有的类实现全部使用智能指针重构5. 任务系统(多线程加载任务)8引入图层(Layer)1. 介绍图层的概念以及重要性2. 图层类实现3. 修改框架(使用图层的方式重构框架)9Layer-bug排查(绘制过程中出现错位,偶发)1. 框架重构后遇到问题(绘制结果错误)2. 瓦片索引方式发生变化,多线程中引起内存问题3. 修改索引方式,解决绘制偶发错误问题10引入数据源(TileSource)1. 数据源的作用与设计目的2. 当前存在的问题,数据调度中存在问题3. 数据源(TileSource)类实现11数据格式管理(FormatMgr)1. 数据格式管理(FormatMgr) 提出的目的,需要解决的问题2. CELLFormat基类接口抽象3. 实现几个标准格式类4. 修改框架流程,使用FormatMgr重构流程5. 扩展支持,后续支持任务格式数据加入系统12Task(任务)优化1. 任务中低耦合数据结构,目的是让Task更加的通用2. 修改任务读取代码与任务处理代码,完善处理流程DEM高程13DEM-数字高程定义1. 什么是数字化高程数据2. 当下GIS系统中有哪些常见的高程格式3. 课程体体系中使用的哪种格式4. 高程类定义以及实现,并加入到FormatMgr 管理系统中14高程瓦片数据读取1. 介绍GIS系统相关的工具(在数据转换)数据生成方面可以解决大量时间2. 自定义高程瓦片格式说明3. 自定义高程格式文件解析,并以智能对象的方式引入到系统中4. 完善框架代码,适配高程数据15高程瓦片文件的读取1. 实现基本的读取算法2. 增加格式化组件,并加入到系统中3. 配置高程图层以及高程数据源,并加载数据,验证数据正确性16瓦片数据结构重构1.顶点生成2.UV坐标计算3.面数据生成17DEM重构绘制流程1. 修改绘制数据结构,去除无用字段2. 增加Mesh类,实现光栅数据转换成三角面数据,计算UV数据,提炼接口3. 修改系统调度,实现顶点数据,UV数据,以及面数据的生成与更新4. 按需更新数据,而不是每一帧更新18DEM-数据精度问题(CPU)1. 因为瓦片数据使用大地坐标作为系统输入,造成瓦片坐标很大,单浮点数据精度不够2. 使用局部坐标的方式解决单浮点精度问题3. 调整相机参数,解决投影矩阵数据计算深度精度问题4. 修改绘制shader 实现对瓦片数据的绘制19DEM-数据精度问题(LogDepth)1. 使用对数深度(log depth )算法在GPU中 计算解决单浮点经纬计算问题2. 修改shader ,增加对(logDepth)算法支持3. 修改C++端代码,实现对shader数据的输入20DEM-数据结构优化1.当下使用CPU端数据通过接口的方式传递给GPU,速度慢2. 使用Instance 方式降低Vertex Buffer 的大小,优化渲染系统21DEM-GPU缓冲区优化1. 使用Vertex Buffer Object / Index Buffer Object  / Instance  方式优化渲染系统2. 修改绘制接口,使用DrawElementsInstanceBaseInstance方式提升系统性能内存池与对象池22瓦片生成优化/对象池1. 相机移动过程中会频繁的建立与释放瓦片,对CPU有较大的消耗2. 引入内存池,避免频繁的内存申请与释放,降低CPU时间3. 改造智能指针对象,对象释放通知到内存管理,回收对象内存23改造任务系统支持对象池1. 任务系统是一个公用模块,被多个模块使用,避免频繁的内存操作,引起的内存碎片2. 实现对象池,并应用到任务模块法线计算24法线计算1. 修改现有顶点结构,增加法线支持2. 修改shader,增加法线顶点输入,使用平行光光照模型3. 修改绘制流程,支持光照计算,使用探照灯作为光源输入25顶点法线计算/共享法线计算1. 增加数据结构保存顶点数据被多个面共享的次数2. 计算面法线,并累加到顶点法线中3. 根据顶点被面共享的次数做平均法线计算4. 修改流程,按需更新法线数据26法线数据压缩1. 法线数据使用3 * float 数据存储,大大的增加了系统的数据2. 实现算法,将3 * float 数据压缩成4字节数据3. 改造绘制代码,支持压缩数据输入27GPU中计算产生法线数据(去掉CPU中计算)1. 引擎支持 Geometry Shader 阶段2. 编写 Geometry Shader,实现法线计算系统功能优化28重构CPU拾取流程1. 当下的拾取流程,只支撑二维数据拾取,无法准群的拾取三维数据2. Terrain中增加拾取接口,输入射线,输出拾取到顶点数据29绘制拾取结果1. 增加一个绘制点的方法,实现绘制代码2. 修改shader,增加logdepth3. 调试代码,花费了很多时间排查错误,最总排查到是因为uniform参数笔误写错造成。30任务系统完善,避免任务队列无线膨胀1. 任务系统中,没有限制队列的大小,生产者的能力远大于消费者的能力,造成任务队列膨胀2. 处理办法,限制生产者的生产能力,而不是限制任务队列大小(这种方式会造成业务逻辑异常复杂)3. 使用sleep休眠方式(这种方式是严重错误的)31如何避免瓦片数据抖动1. 产生瓦片抖动的原因 ? 分裂算法与回退算法中间没有过度2. 引入过度流程,避免内存抖动,参数因子是一个重要的数据,需要谨慎使用3. 有必要结合瓦片自身数据动态计算参数因子32瓦片数据管理-fepk文件格式支持-全球数据加载1. 支持fepk文件格式,增加fepk读取组件,适配fepk文件2. fepk管理数据方式:一般情况选择全球前10级别作为基础级别,因数据量不大(1G)左右,后续以8级作为基础级别,全球19级别数据被划分为 2^8 * 2^7(512 * 256)个块。每个块中包含了256 * 256 张小瓦片33fepk高程数据读取 34高程分裂处理当瓦片没有高程数据,那么子节点以及其他后代节点该如何共享父节点的数据35lesson-734-高程瓦片分裂处理(2)-算法实现高程数据分裂算法实现实现对高程数据的切分,并对特殊数据进行处理36高程瓦片分裂处理(3)-问题排查 37高程瓦片分裂处理(4)-(后代节点更新问题)当一个瓦片高程数据更新后,他的儿子节点,孙子节点...该如何处理?38瓦片视锥裁剪错误高程数据更新后,没有技术计算瓦片包围盒信息,造成包围盒错误,进而引视锥计算错误39http支持1.引入三方库 Libcurl2.http类封装,支持http读取数据40fepk.server使用 生成三维地球41改造四叉树-统一使用经纬度输入42地形网络生成算法重构 43引入球体坐标系 44使用球体坐标改造瓦片 45多图层(加载标签数据) 课时截图:镜头拉近后,显示细节数据加载矢量SHP国界线数据:加载矢量三维白膜数据截图高程数据加载点云数据 加载倾斜摄影数据 

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧