private void addTopLevelMetrics(final Traversal.Admin traversal, final boolean onGraphComputer) { this.totalStepDuration = 0; final List<ProfileStep> profileSteps = TraversalHelper.getStepsOfClass(ProfileStep.class, traversal); final List<Pair<Integer, MutableMetrics>> tempMetrics = new ArrayList<>(profileSteps.size()); for (int ii = 0; ii < profileSteps.size(); ii++) { // The index is necessary to ensure that step order is preserved after a merge. final ProfileStep step = profileSteps.get(ii); final MutableMetrics stepMetrics = onGraphComputer ? traversal.getSideEffects().get(step.getId()) : step.getMetrics(); this.totalStepDuration += stepMetrics.getDuration(MutableMetrics.SOURCE_UNIT); tempMetrics.add(Pair.with(ii, stepMetrics.clone())); } tempMetrics.forEach(m -> { final double dur = m.getValue1().getDuration(TimeUnit.NANOSECONDS) * 100.d / this.totalStepDuration; m.getValue1().setAnnotation(PERCENT_DURATION_KEY, dur); }); tempMetrics.forEach(p -> { this.stepIndexedMetrics.put(p.getValue1().getId(), p.getValue1().getImmutableClone()); this.positionIndexedMetrics.put(p.getValue0(), p.getValue1().getImmutableClone()); }); }
@Override public void apply(final Traversal.Admin<?, ?> traversal) { if ((traversal.getParent() instanceof EmptyStep || traversal.getParent() instanceof VertexProgramStep) && TraversalHelper.hasStepOfAssignableClassRecursively(ProfileSideEffectStep.class, traversal)) TraversalHelper.applyTraversalRecursively(t -> t.getEndStep().addLabel(MARKER), traversal); if (traversal.getEndStep().getLabels().contains(MARKER)) { traversal.getEndStep().removeLabel(MARKER); // Add .profile() step after every pre-existing step. final List<Step> steps = traversal.getSteps(); final int numSteps = steps.size(); for (int i = 0; i < numSteps; i++) { // Do not inject profiling after ProfileSideEffectStep as this will be the last step on the root traversal. if (steps.get(i * 2) instanceof ProfileSideEffectStep) break; // Create and inject ProfileStep traversal.addStep((i * 2) + 1, new ProfileStep(traversal)); } } }
private void initializeIfNeeded() { if (null == this.metrics) { this.onGraphComputer = TraversalHelper.onGraphComputer(this.getTraversal()); this.metrics = new MutableMetrics(this.getPreviousStep().getId(), this.getPreviousStep().toString()); final Step<?, S> previousStep = this.getPreviousStep(); // give metrics to the step being profiled so that it can add additional data to the metrics like // annotations if (previousStep instanceof Profiling) ((Profiling) previousStep).setMetrics(this.metrics); } }
@Override public Traverser.Admin<S> next() { Traverser.Admin<S> start = null; this.initializeIfNeeded(); this.metrics.start(); try { start = super.next(); return start; } finally { if (start != null) { this.metrics.finish(start.bulk()); if (this.onGraphComputer) { this.getTraversal().getSideEffects().add(this.getId(), this.metrics); this.metrics = null; } } else { this.metrics.stop(); if (this.onGraphComputer) { this.getTraversal().getSideEffects().add(this.getId(), this.metrics); this.metrics = null; } } } }
((ProfileStep) step).getMetrics();
this.traversal.get().getSideEffects().register(profileStep.getId(), new MutableMetricsSupplier(profileStep.getPreviousStep()), ProfileStep.ProfileBiOperator.instance());
@Override public MemoryComputeKey<MutableMetrics> getMemoryComputeKey() { return MemoryComputeKey.of(this.getId(), ProfileBiOperator.instance(), false, true); }
@Override public boolean hasNext() { initializeIfNeeded(); this.metrics.start(); boolean ret = super.hasNext(); this.metrics.stop(); return ret; }
@Override public Traverser.Admin<S> next() { Traverser.Admin<S> start = null; this.initializeIfNeeded(); this.metrics.start(); try { start = super.next(); return start; } finally { if (start != null) { this.metrics.finish(start.bulk()); if (this.onGraphComputer) { this.getTraversal().getSideEffects().add(this.getId(), this.metrics); this.metrics = null; } } else { this.metrics.stop(); if (this.onGraphComputer) { this.getTraversal().getSideEffects().add(this.getId(), this.metrics); this.metrics = null; } } } }
@Override protected Traverser.Admin<S> processNextStart() throws NoSuchElementException { if (!rootSchemaTableTrees.isEmpty()) { rootSchemaTableTrees.forEach(this::process); rootSchemaTableTrees.clear(); if (getNextStep() instanceof ProfileStep<?>) { // TODO Should we return a traverser with the count of updated rows so it looks like we did something? ((ProfileStep<?>) getNextStep()).getMetrics().incrementCount(TraversalMetrics.TRAVERSER_COUNT_ID, 1); ((ProfileStep<?>) getNextStep()).getMetrics().incrementCount(TraversalMetrics.ELEMENT_COUNT_ID, 1); } } // Basically we flat map to nothing every time throw FastNoSuchElementException.instance(); }
this.traversal.get().getSideEffects().register(profileStep.getId(), new MutableMetricsSupplier(profileStep.getPreviousStep()), ProfileStep.ProfileBiOperator.instance());
@Override public void workerIterationEnd(final Memory memory) { // store profile metrics in proper ProfileStep metrics if (this.profile) { List<ProfileStep> profileSteps = TraversalHelper.getStepsOfAssignableClassRecursively(ProfileStep.class, this.traversal.get()); // guess the profile step to store data int profileStepIndex = memory.getIteration(); // if we guess wrongly write timing into last step profileStepIndex = profileStepIndex >= profileSteps.size() ? profileSteps.size() - 1 : profileStepIndex; this.iterationMetrics.finish(0); // reset counts this.iterationMetrics.setCount(TraversalMetrics.TRAVERSER_COUNT_ID,0); if (null != MemoryTraversalSideEffects.getMemorySideEffectsPhase(this.traversal.get())) { this.traversal.get().getSideEffects().add(profileSteps.get(profileStepIndex).getId(), this.iterationMetrics); } this.iterationMetrics = null; } }
@Override public boolean hasNext() { initializeIfNeeded(); this.metrics.start(); boolean ret = super.hasNext(); this.metrics.stop(); return ret; }
private void addTopLevelMetrics(final Traversal.Admin traversal, final boolean onGraphComputer) { this.totalStepDuration = 0; final List<ProfileStep> profileSteps = TraversalHelper.getStepsOfClass(ProfileStep.class, traversal); final List<Pair<Integer, MutableMetrics>> tempMetrics = new ArrayList<>(profileSteps.size()); for (int ii = 0; ii < profileSteps.size(); ii++) { // The index is necessary to ensure that step order is preserved after a merge. final ProfileStep step = profileSteps.get(ii); final MutableMetrics stepMetrics = onGraphComputer ? traversal.getSideEffects().get(step.getId()) : step.getMetrics(); this.totalStepDuration += stepMetrics.getDuration(MutableMetrics.SOURCE_UNIT); tempMetrics.add(Pair.with(ii, stepMetrics.clone())); } tempMetrics.forEach(m -> { final double dur = m.getValue1().getDuration(TimeUnit.NANOSECONDS) * 100.d / this.totalStepDuration; m.getValue1().setAnnotation(PERCENT_DURATION_KEY, dur); }); tempMetrics.forEach(p -> { this.stepIndexedMetrics.put(p.getValue1().getId(), p.getValue1().getImmutableClone()); this.positionIndexedMetrics.put(p.getValue0(), p.getValue1().getImmutableClone()); }); }
((ProfileStep) step).getMetrics();
private void initializeIfNeeded() { if (null == this.metrics) { this.onGraphComputer = TraversalHelper.onGraphComputer(this.getTraversal()); this.metrics = new MutableMetrics(this.getPreviousStep().getId(), this.getPreviousStep().toString()); final Step<?, S> previousStep = this.getPreviousStep(); // give metrics to the step being profiled so that it can add additional data to the metrics like // annotations if (previousStep instanceof Profiling) ((Profiling) previousStep).setMetrics(this.metrics); } }
@Override public MemoryComputeKey<MutableMetrics> getMemoryComputeKey() { return MemoryComputeKey.of(this.getId(), ProfileBiOperator.instance(), false, true); }
@Override public void apply(final Traversal.Admin<?, ?> traversal) { if ((traversal.getParent() instanceof EmptyStep || traversal.getParent() instanceof VertexProgramStep) && TraversalHelper.hasStepOfAssignableClassRecursively(ProfileSideEffectStep.class, traversal)) TraversalHelper.applyTraversalRecursively(t -> t.getEndStep().addLabel(MARKER), traversal); if (traversal.getEndStep().getLabels().contains(MARKER)) { traversal.getEndStep().removeLabel(MARKER); // Add .profile() step after every pre-existing step. final List<Step> steps = traversal.getSteps(); final int numSteps = steps.size(); for (int i = 0; i < numSteps; i++) { // Do not inject profiling after ProfileSideEffectStep as this will be the last step on the root traversal. if (steps.get(i * 2) instanceof ProfileSideEffectStep) break; // Create and inject ProfileStep traversal.addStep((i * 2) + 1, new ProfileStep(traversal)); } } }
@Override public void workerIterationEnd(final Memory memory) { // store profile metrics in proper ProfileStep metrics if (this.profile) { List<ProfileStep> profileSteps = TraversalHelper.getStepsOfAssignableClassRecursively(ProfileStep.class, this.traversal.get()); // guess the profile step to store data int profileStepIndex = memory.getIteration(); // if we guess wrongly write timing into last step profileStepIndex = profileStepIndex >= profileSteps.size() ? profileSteps.size() - 1 : profileStepIndex; this.iterationMetrics.finish(0); // reset counts this.iterationMetrics.setCount(TraversalMetrics.TRAVERSER_COUNT_ID,0); if (null != MemoryTraversalSideEffects.getMemorySideEffectsPhase(this.traversal.get())) { this.traversal.get().getSideEffects().add(profileSteps.get(profileStepIndex).getId(), this.iterationMetrics); } this.iterationMetrics = null; } }