ChartsOrg / Charts

Beautiful charts for iOS/tvOS/OSX! The Apple side of the crossplatform MPAndroidChart.
Apache License 2.0
27.6k stars 6k forks source link

Performance hit between V3.2.1 and V3.0.2 #3699

Open thierryH91200 opened 6 years ago

thierryH91200 commented 6 years ago

What did you do?

I compare V3.0.2 and 3.2.1

What did you expect to happen?

the same performance

What happened instead?

Not the same performance

Charts Environment

Charts version/Branch/Commit Number: Xcode version:Version 10.1 beta 3 (10O45e) Swift version:3 and 4.2 Platform(s) running Charts:OSX macOS version running Xcode:10.14

Demo Project

the file source for the graph Line is the same for the 2 versions with V3.2.1 that's not really good

charts mov 302 and 321.zip

ℹ Please link to or upload a project we can download that reproduces the issue.

pmairoldi commented 6 years ago

With the normal demos. I don't see the performance issues. Are your using a large data set or something? We need for details.

thierryH91200 commented 6 years ago

yes I use a large data set for the Mac for the mac with version 3.2.1 there is a CPU problem

rongboyang commented 5 years ago

I also see a performance issue from 3.1.1 to 3.2.1.

wolfAle commented 5 years ago

Hi,

I never used the 3.1.1 but there's totally a performance issue on 3.2.1, with large amount of data (I'm talking about 12k-ish entries). I'm experiencing slowness either when setting up the data for the first draw and when using pan/zoom gestures on the drawn graph. It takes a long time to react to the gesture and the only way to get it really responsive is to zoom a lot to reduce the amount of entries shown.

Is there anything I can do to speed the fix process up?

Thanks

tdimeco commented 5 years ago

Hi,

Same issue here, huge performance decrease since 3.2.0. See attached videos. The top graph contains approx. 5000 values. This does not seems to be fixed in 3.3.0.

I'll try to create a sample project.

Thanks!

3.1.1 vs 3.2.0+.zip

tdimeco commented 5 years ago

Here is the sample project. Check out the project README. The graph rendering pass seems to be 15x slower since 3.2.0!

Download: ChartsPerf.zip

chartsperf

thierryH91200 commented 5 years ago

i have found the solution

drawCircles is very long and dataSet.isDrawCirclesEnabled is not tested

charts/renderers/chartsRenderers/LineChartRenderer

in private func drawCircles(context: CGContext)

    private func drawCircles(context: CGContext)
    {
        guard
            let dataProvider = dataProvider,
            let lineData = dataProvider.lineData
            else { return }

        let phaseY = animator.phaseY

        let dataSets = lineData.dataSets

        var pt = CGPoint()
        var rect = CGRect()

        context.saveGState()

        for i in 0 ..< dataSets.count
        {
            guard let dataSet = lineData.getDataSetByIndex(i) as? LineChartDataSetProtocol else { continue }

            if !dataSet.isVisible || **!dataSet.isDrawCirclesEnabled** || dataSet.entryCount == 0
            {
                continue
            }

and

dataSet.drawCirclesEnabled = false

mailsonncosta commented 5 years ago

Hi everyone.

I got the same performance issue when I updated to the 3.2.1 version, the xAxis animation is too slow (it gets stuck in some points) when a lot of data is applied to the data set and the option 'drawCirclesEnabled' is already configured to false.

thierryH91000 commented 5 years ago

drawCirclesEnabled Is not tested

Natai commented 5 years ago

can not believe the bug remain almost one year。。。 performance still is very bad in v3.3.0

pmairoldi commented 5 years ago

Keep in mind that most of us are doing this in our spare time. We are busy with others things such as our jobs and families. We are always more than happy to merge in a fix that is sent by the community.

tdimeco commented 4 years ago

Hi everybody,

Today I dig a little bit to find where the performance bottleneck is coming from. I have found something. By watching the diff between 3.1.1 and 3.2.0, I have found that accessibility code were added to charts renderers. The one in BarChartRenderer is interested:

// Create and append the corresponding accessibility element to accessibilityOrderedElements
if let chart = dataProvider as? BarChartView
{
    let element = createAccessibleElement(withIndex: j,
                                          container: chart,
                                          dataSet: dataSet,
                                          dataSetIndex: index,
                                          stackSize: stackSize)
    { (element) in
        element.accessibilityFrame = barRect
    }

    accessibilityOrderedElements[j/stackSize].append(element)
}

Link to code

I use my sample Xcode Project (the one from my previous message above). It renders a BarChart with 20k values. Here are the results:

In 3.1.1, the view takes 0.7s to render.

In 3.2.0+, the delay increases to 7s. If I comment the append array line (accessibilityOrderedElements[j/stackSize].append(element)), the delay drops to 0.9s. Then, if I comment the entire block (if let chart...), the delay drops back to 0.7s.

To summarise:

The construction of the accessibility array seems to be the bottleneck here. accessibilityOrderedElements is a [[NSUIAccessibilityElement]], I tried to optimise it even better, by pre-allocating the array and the subarrays, and by assigning using something like accessibilityOrderedElements[j/stackSize][j%stackSize] = element. I also try to flatten the array and not using subarrays, etc. I did not manage to improve anything.

So, I have 2 questions:

  1. Do somebody have an idea to improve the construction of the accessibility array?
  2. Is it relevant to construct an accessibility array for graphs with 20k elements? Voiceover users will unlikely wait for 20k elements to be pronounced. Maybe app designers should instead hide the graph and provide useful computed values like min/max/average for blind people? Am I right? If so, maybe we can think about stopping the construction of the accessibility array if the graph contains more than N elements?

Thank you for your time! :)