Insufficient Performance of PPTX generation (Java)

Hello,

The target of the code below is to compose one presentation from several slides. The generation of the final presentation takes too much time. Is it a problem with our code or a problem of Aspose.Slides library. Actually, on this level of performance the Aspose.Slides library becomes relatively impossible to use in production.
The code is below and source PPTX’s are here (https://slidedeckdev.blob.core.windows.net/slidedeck/slidedeck/Archive.zip).

package com.luxoft.slidedeck.export.sandbox;

import com.aspose.slides.BlobManagementOptions;
import com.aspose.slides.IBlobManagementOptions;
import com.aspose.slides.LoadOptions;
import com.aspose.slides.Presentation;
import com.aspose.slides.SaveFormat;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.io.ByteStreams;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Objects;
import java.util.Stack;
import java.util.logging.Logger;

public class TestExport {

    public static void main(String[] args) throws IOException {
        System.out.println("Working...");
        new TestExport().run();
    }

    private final Stack<LocalDateTime> timeLine = new Stack<>();

    private final StringBuilder log = new StringBuilder();

    public TestExport() {
    }

    public void run() throws IOException {

        byte[] dstPresentationContent = readResource("master.pptx");

        List<byte[]> srcPresentationsContent = ImmutableList.of(
                readResource("slide1.pptx"),
                readResource("slide2.pptx"),
                readResource("slide3.pptx"),
                readResource("slide4.pptx"),
                readResource("slide5.pptx")
        );

        ByteArrayOutputStream resultOutputStream = new ByteArrayOutputStream((srcPresentationsContent.size() + 1) * 10 * 1024 * 1024);

        begin("entire process");

        begin("open master");
        LoadOptions lo = new LoadOptions();
        IBlobManagementOptions bmo = new BlobManagementOptions();
        lo.setBlobManagementOptions(bmo);
        bmo.setTemporaryFilesAllowed(false);

        Presentation dstPresentation = new Presentation(new ByteArrayInputStream(dstPresentationContent), lo);
        end("open master");

        for (byte[] srcPresentationContent : srcPresentationsContent) {
            begin("open slide");
            Presentation srcPresentation = new Presentation(new ByteArrayInputStream(srcPresentationContent), lo);
            end("open slide");

            begin("clone slide");
            dstPresentation.getSlides().addClone(srcPresentation.getSlides().get_Item(0));
            end("clone slide");

            begin("dispose slide");
            srcPresentation.dispose();
            end("dispose slide");
        }

        begin("write result");
        dstPresentation.save(resultOutputStream, SaveFormat.Pptx);
        end("write result");

        begin("dispose master");
        dstPresentation.dispose();
        end("dispose master");

        end("entire process");

        // TODO write result to file

        Preconditions.checkState(timeLine.isEmpty());

        Logger.getLogger("com.luxoft.slidedeck.api.controllers.CategoriesController").info(log.toString());
    }

    private void begin(String actionName) {
        LocalDateTime now = LocalDateTime.now();
        if (timeLine.isEmpty()) {
            log.append("\n");
        }
        timeLine.push(now);
        log.append(String.format("%s started\n", actionName));
    }

    private void end(String actionName) {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime than = timeLine.pop();
        log.append(String.format("%s ended took %8.2f seconds\n", actionName, ((float) ChronoUnit.MILLIS.between(than, now)) / 1000));
        if (timeLine.isEmpty()) {
            log.append("------------------------------\n");
        }
    }

    private byte[] readResource(String name) throws IOException {
        InputStream inputStream = getClass().getClassLoader().getResourceAsStream(name);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(1024 * 1024);
        ByteStreams.copy(Objects.requireNonNull(inputStream), outputStream);
        return outputStream.toByteArray();
    }

}

@JStepina_luxoft_com,

I have observed the sample code shared along with presentation files. You are in fact performing slide cloning to merge all presentation files in one deck. I like to share that performing slide cloning is one of resource consuming process in Aspose.Slides. However, I still request you to please first try using latest Aspose.Slides for Java 19.12 on your end. If there is still performance related shortcomings as per your assessment then please provide the output of above sample code in terms of time consumed. Please also share the Operating System, Machine statistics and Java details on your end. We will be able to proceed further on our end on provision of requested information.

Isn’t a BlobManagement deprecated in Java? It is in C# so i thought that it’s also deprecated in Java.

@obrusentsov,

Please check this API reference link for BlobOptions. It has not been deprecated.