NPOI Alternative Spreadsheet API Performance Test in C# .NET
Tags: webdev, dotnet, devops, csharp
Published: 2022-06-03 21:27:25

---
canonical_url: https://www.grapecity.com/blogs/npoi-alternative-spreadsheet-api-performance-test-c-sharp-net
description: Learn about the performance of an NPOI alternative spreadsheet API in this C# .NET test. See more today.
---

[GrapeCity Documents for Excel (GcExcel)](https://www.grapecity.com/en/documents-api-excel) is a fast, high-performance spreadsheet API that requires no dependencies on Excel. With full .NET 6 support, you can generate, load, modify, and convert Excel .xlsx spreadsheets in a .NET Framework, .NET Core, Mono, and Xamarin.

We have continually been monitoring the performance of GcExcel with every release. We recorded the performance time and memory consumed for load, save, and calculation operations of GcExcel in comparison with other competitors on Windows, macOS, and Linux platforms. From our rigorous performance tests, we are confident GcExcel will be an excellent replacement for those looking for an alternative to NPOI or similar other APIs to enhance their current applications' performance.

### Performance Metrics and Data

**Test Machine Configurations**

*   Windows: Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz 3.19 GHz, x64-based processor, Windows 10 Pro 20H2 Build 19042.1052
*   MacOS: Intel i9 @ 2.3 GHz / MacOS Catalina v10.15.6
*   Linux: CPU: 4 core Intel(R) Xeon(R) CPU E5-2683 v3 @ 2.00GHz, 4GB

**Builds Used for Comparison**

This comparison references the following build version of GcExcel and competitor:

*   [GcExcel - v5.1.1](https://www.grapecity.com/documents-api-excel/download)
*   Competitor#1
*   Competitor#2 ([NPOI - v2.5.6](https://www.nuget.org/packages/NPOI/))

**Test Data**

The **first three tests** populate **100,000 rows x 30 columns** (3,000,000 cells) with type double, string, and date values, measuring the performance for **Set Values**, **Get Values**, and **Save to XLSX. The** total **Memory Used** (which is difficult to measure accurately since garbage collection can happen at any time).

These tests look like this (the **string test** uses the hard-coded string value **"ABCDEFGHIJKLMNOPQRSTUVWXYZ"** and the **date test** creates a **new Date()** object but are otherwise the same):

**GcExcel Double Performance Test**

 

```
   public static void TestSetRangeValues_Double(int rowCount, int columnCount, ref double setTime, ref double getTime, ref double saveTime, ref double usedMem)
    {

                Console.WriteLine();    
                Console.WriteLine(string.Format("GcExcel benchmark for double values with {0} rows and {1} columns", rowCount, columnCount));

                IWorkbook workbook = new Workbook();
                IWorksheet worksheet = workbook.Worksheets[0];

                Stopwatch watch = new Stopwatch();
                watch.Start();

                double[,] values = new double[rowCount, columnCount];

                for (int i = 0; i < rowCount; i++)
                {
                    for (int j = 0; j < columnCount; j++)
                    {
                        values[i, j] = i + j;
                    }
                }

                worksheet.Range[0, 0, rowCount, columnCount].Value = values;
                watch.Stop();

                setTime = watch.ElapsedMilliseconds / 1000d;
                Console.WriteLine(string.Format("GcExcel set double values: {0:N3} s", setTime));

                watch.Start();
                object tmpValues = worksheet.Range[0, 0, rowCount, columnCount].Value;
                watch.Stop();

                getTime = watch.ElapsedMilliseconds / 1000d; ;
                Console.WriteLine(string.Format("GcExcel get double values: {0:N3} s", getTime));

                watch.Start();
                workbook.Save("../../output/gcexcel-saved-doubles.xlsx");
                watch.Stop();
                saveTime = watch.ElapsedMilliseconds / 1000d; ;
                Console.WriteLine(string.Format("GcExcel save doubles to Excel: {0:N3} s", saveTime)); }
```

The **last two tests** focus more on **calculation performance**.

In following test, the workbook loads a **large XLSX** which contains **many formulas using volatile functions** that require recalculation each time the worksheet is calculated and measures the performance for **Open File**, **Calculate**, **Save to XLSX**, and the total **Memory Used**.

This test looks like this:

**GcExcel Open Large XLSX Performance Test**

 

```
   public static void TestBigExcelFile(int rowCount, int columnCount, ref double openTime, ref double calcTime, ref double saveTime, ref double usedMem)
    {

                Console.WriteLine();    
                   Console.WriteLine(string.Format("GcExcel benchmark for test-performance.xlsx which is 20.5MB with a lot of values, formulas and styles"));

                IWorkbook workbook = new Workbook();

                Stopwatch watch = new Stopwatch();
                watch.Start();
                workbook.Open("../../files/test-performance.xlsx");
                watch.Stop();

                openTime = watch.ElapsedMilliseconds / 1000d; ;
                Console.WriteLine(string.Format("GcExcel open big Excel: {0:N3} s", openTime));

                watch.Start();
                workbook.Dirty();
                workbook.Calculate();
                watch.Stop();

                calcTime = watch.ElapsedMilliseconds / 1000d; ;
                Console.WriteLine(string.Format("GcExcel calculate formulas for big Excel: {0:N3} s", calcTime));

                watch.Start();
                workbook.Save("../../output/gcexcel-saved-test-performance.xlsx");
                watch.Stop();
                saveTime = watch.ElapsedMilliseconds / 1000d; ;
                Console.WriteLine(string.Format("GcExcel save back to big Excel: {0:N3} s", saveTime));
    }
```

The following test populates **100,000 rows x 2 columns** of double values, then **sets formulas** to a range of **100,000 rows x 30 columns** adjacent to and referencing those double values in the first 2 columns, measuring the performance for **Set Formulas**, **Calculate**, **Save to XLSX**, and the total **Memory Used**.

This test looks like this:

**GcExcel Formulas Performance Test**

```
    public static void TestSetRangeFormulas(int rowCount, int columnCount, ref double setTime, ref double calcTime, ref double saveTime, ref double usedMem)
    {             
                Console.WriteLine();
                Console.WriteLine(string.Format("GcExcel benchmark for double values with {0} rows and {1} columns", rowCount, columnCount));

                IWorkbook workbook = new Workbook();
                workbook.ReferenceStyle = ReferenceStyle.R1C1;
                IWorksheet worksheet = workbook.Worksheets[0];

                double[,] values = new double[rowCount, 2];

                for (int i = 0; i < rowCount; i++)
                {
                    for (int j = 0; j < 2; j++)
                    {
                        values[i, j] = i + j;
                    }
                }
                worksheet.Range[0, 0, rowCount, 2].Value = values;

                Stopwatch watch = new Stopwatch();
                watch.Start();
                worksheet.Range[0, 2, rowCount - 2, columnCount].Formula = "=SUM(RC[-2],RC[-1])";
                watch.Stop();

                setTime = watch.ElapsedMilliseconds / 1000d; ;
                Console.WriteLine(string.Format("GcExcel set formulas: {0:N3} s", setTime));

                watch.Start();
                workbook.Calculate();
                watch.Stop();

                calcTime = watch.ElapsedMilliseconds / 1000d; ;
                Console.WriteLine(string.Format("GcExcel calculates formula: {0:N3} s", calcTime));

                workbook.ReferenceStyle = ReferenceStyle.A1;

                watch.Start();
                workbook.Save("../../output/gcexcel-saved-formulas.xlsx");
                watch.Stop();
                saveTime = watch.ElapsedMilliseconds / 1000d; ;
                Console.WriteLine(string.Format("GcExcel save formulas to Excel: {0:N3} s", saveTime));
    }

```

### Performance Results

Following are the [PerformanceTestResults.xlsx](https://wiki.grapecity.io/download/attachments/1220118328/PerformanceTestResults.xlsx?version=4&modificationDate=1652757166073&api=v2):

GcExcel performs better than other competitors in various operations on loading, modifying, and saving the Excel file. Have a look at the numbers below.

![Results](https://files.grapecity.com/gc-website-media/xado4fno/01-npoi.png?width=500&height=197.7653631284916)

**Note:** The results were taken on particular machine configurations. If you are running at a different configuration, the values may not match our collected results exactly. If you observe any discrepancies in the overall performance, please leave your comments below.

Also, check out Performance Comparison of older build and [Feature comparison](https://www.grapecity.com/blogs/npoi-apache-poi-alternative-gcexcel-net) with NPOI.