动态或静态地描绘数据以加速发送数据

时间:2014-02-07 15:48:53

标签: c# performance

我有6000到6000,000个数据,这些数据必须发送到串口。我每隔3-5毫秒将数据发送到串口。在发送数据之前,我必须对它进行一些计算(例如对一些数据采用sin,cos)并在图表上描绘数据。每次我发送数据我在图表上描述它然后计算下一个数据但是这个方式有点慢(有时需要的时间超过3-5毫秒)。

可以通过以下方式加快我的计划吗?他们是正确的方式吗?

  首先完全计算运动图表(例如,   对于x = 0到5000000,100sin(.0001 * Index + 10)并将其存储在数组中   然后,当我向端口发送数据时,我必须在数组中找到数据   然后描绘并发送它。

     

2 - 如上所述,但将其存储在文件中   从文件中读取。

假设这是我的代码:

namespace WPF_Toolkit_SpeedTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public ObservableCollection<ChartItem> Items { set; get; }

        public MainWindow()
        {
            InitializeComponent();
        }
        #region winmm.dll functions
        int _counter = 0;
        public delegate void TimerEventHandler(UInt32 id, UInt32 msg, ref UInt32 userCtx, UInt32 rsv1, UInt32 rsv2);

        /// <summary>
        /// A multi media timer with millisecond precision
        /// </summary>
        /// <param name="msDelay">One event every msDelay milliseconds</param>
        /// <param name="msResolution">Timer precision indication (lower value is more precise but resource unfriendly)</param>
        /// <param name="handler">delegate to start</param>
        /// <param name="userCtx">callBack data </param>
        /// <param name="eventType">one event or multiple events</param>
        /// <remarks>Dont forget to call timeKillEvent!</remarks>
        /// <returns>0 on failure or any other value as a timer id to use for timeKillEvent</returns>
        [DllImport("winmm.dll", SetLastError = true, EntryPoint = "timeSetEvent")]
        static extern UInt32 timeSetEvent(UInt32 msDelay, UInt32 msResolution, TimerEventHandler handler, ref UInt32 userCtx, UInt32 eventType);

        /// <summary>
        /// The multi media timer stop function
        /// </summary>
        /// <param name="uTimerID">timer id from timeSetEvent</param>
        /// <remarks>This function stops the timer</remarks>
        [DllImport("winmm.dll", SetLastError = true)]
        static extern void timeKillEvent(UInt32 uTimerID);

        TimerEventHandler tim;//TimerEventHandler tim = new TimerEventHandler(this.Link);
        public void Link(UInt32 id, UInt32 msg, ref UInt32 userCtx, UInt32 rsv1, UInt32 rsv2)
        {
            _counter++;
            if ((_counter % 5) == 0) //if ((_counter % 10) == 0)
            {
                Dispatcher.Invoke(new Action(()=>{
                    Items.Add(new ChartItem(_counter, 100*Math.Sin((.0002*_counter))));
                    if (_counter>1000)
                    {
                        Items.RemoveAt(0);
                    }
                }));
            }

            if (_counter > 10000)
            {
                timeKillEvent(id);
                Dispatcher.Invoke(new Action(() => { button1.Content = stp.ElapsedMilliseconds; }));
            }
        }
        uint timerId;
        #endregion 

        private void button1_Click(object sender, RoutedEventArgs e)
        {

            Items = new ObservableCollection<ChartItem>();
            lineChart.ItemsSource = Items;

            Items.Add(new ChartItem(0, 0));
            tim = new TimerEventHandler(this.Link);
            uint rsv = 0;
            stp.Start();
            button1.Content = stp.ElapsedMilliseconds;
            timerId = timeSetEvent(1, 1, tim, ref rsv, 1);
        }
        System.Diagnostics.Stopwatch stp = new System.Diagnostics.Stopwatch();
    }
    public class ChartItem : INotifyPropertyChanged
    {
        public ChartItem(double t, double v)
        {
            time = t;
            myVar = v;
        }

        private double time;

        public double Time
        {
            get { return time; }
            set
            {
                time = value;
                OnPropertyChanged("Time");
            }
        }

        private double myVar;

        public double Value
        {
            get { return myVar; }
            set
            {
                myVar = value;
                OnPropertyChanged("Value");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

此代码仅显示描述部分,但同时我也发送数据。

1 个答案:

答案 0 :(得分:0)

似乎你不必要地将I / O绑定代码和CPU绑定代码组合在一起。我说更合适的方法是异步(并立即)发送数据 - 异步和等待使这非常轻松。当然,除非你想要将这两个部分绑定在一起,否则会有一些原因。

此外,似乎你的问题可能稍微复杂一点,因为简单的罪或cos不会花费你整整几毫秒。您是否尝试过分析应用程序以找出真正的问题所在?

例如,如果您在每个步骤中重新创建图表并在某个用户界面中显示该图表,那么您将会出现大幅放缓。 让UI降低您的基础通信速度。相反,刷新UI应该只在偶尔进行一次,理想情况下与下面的数据流分开。

我发现很难相信简单的数学运算足以让你的代码慢下来。我的计算机每毫秒可以轻松完成超过十万次的犯罪操作 - 如果你在绘制图表的同时做了这么多,你就会做出一些可怕的错误:D