ChartsOrg / Charts

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

CPU Utilization in LineChartRenderer.swift #3774

Open Stoodwalk opened 5 years ago

Stoodwalk commented 5 years ago

What did you do?

Updated to Swift 4.2 compliant version of Charts.

What did you expect to happen?

Swift 4.2 compliance

What happened instead?

Everything went smoothly, except that the CPU utilization increased significantly from ~33% to ~90% while presenting a continuously updated line chart 15 times a second resulting in choppy visual performance.

However, I was able to find in LineChartRenderer.swift on line 632 one of the changes from the previous version was the removal of the OR test for !dataSet.isDrawCirclesEnabledfor a continue statement. Which means even though the circles are not drawn, the process still falls through the continue statement executing the code. When I replaced the OR test the CPU utilization returned to where it was previously.

I returned this:

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

Back to this:

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

to regain the performance.

Thanks. Stoodwalk

Charts Environment

Charts 3.2.1/ Version 3.2.1, synced to [MPAndroidChart #f6a398b] Xcode version: 10.1 Swift version: 4.2 Platform(s) running Charts: iOS **macOS version running Xcode: 10.13.6

jjatie commented 5 years ago

@liuxuan30 Seems like a significant bug we should look into

thierryH91200 commented 5 years ago

see #3699

thierryH91200 commented 5 years ago

in LineChartRenderer.swift

private func drawCircles(context: CGContext)

this function takes a lot of time in the last version and it's nice in V3.0.2

if I remove this function and with 10k record it's perfect

i have add for the test

    func printTimeElapsedWhenRunningCode(title:String, operation:()->()) {
        let startTime = CFAbsoluteTimeGetCurrent()
        operation()
        let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
        print("Time elapsed for \(title): \(timeElapsed) s.")
    }

and

        printTimeElapsedWhenRunningCode(title:"drawExtras") {
            renderer.drawExtras(context: context)
        }

the result with the last version is Time elapsed for drawExtras: 3.9924609661102295 s. Time elapsed for drawExtras: 3.962438941001892 s.

and with 3.0.2

Time elapsed for drawExtras: 2.6941299438476562e-05 s. Time elapsed for drawExtras: 1.0013580322265625e-05 s. Time elapsed for drawExtras: 5.0067901611328125e-06 s. Time elapsed for drawExtras: 7.987022399902344e-06 s. Time elapsed for drawExtras: 7.033348083496094e-06 s. Time elapsed for drawExtras: 8.106231689453125e-06 s. Time elapsed for drawExtras: 5.0067901611328125e-06 s. Time elapsed for drawExtras: 6.079673767089844e-06 s. Time elapsed for drawExtras: 5.9604644775390625e-06 s. Time elapsed for drawExtras: 9.059906005859375e-06 s. Time elapsed for drawExtras: 6.079673767089844e-06 s. Time elapsed for drawExtras: 7.033348083496094e-06 s. Time elapsed for drawExtras: 9.059906005859375e-06 s. Time elapsed for drawExtras: 6.9141387939453125e-06 s. Time elapsed for drawExtras: 7.033348083496094e-06 s. Time elapsed for drawExtras: 6.9141387939453125e-06 s. Time elapsed for drawExtras: 9.059906005859375e-06 s. Time elapsed for drawExtras: 7.033348083496094e-06 s. Time elapsed for drawExtras: 7.987022399902344e-06 s. Time elapsed for drawExtras: 6.079673767089844e-06 s. Time elapsed for drawExtras: 7.033348083496094e-06 s. Time elapsed for drawExtras: 6.9141387939453125e-06 s. Time elapsed for drawExtras: 8.106231689453125e-06 s. Time elapsed for drawExtras: 7.033348083496094e-06 s. Time elapsed for drawExtras: 7.033348083496094e-06 s. Time elapsed for drawExtras: 6.079673767089844e-06 s. Time elapsed for drawExtras: 7.987022399902344e-06 s.

darrendavidhumphrey commented 5 years ago

I am seeing the same slowdown and the same improvement by adding the or condition back in.