Performance improvements (#746)

* Misc minor performance improvements

* Use more concise loop syntax

* Use more concise Collection sort syntax

* Use StringUtils pad methods

* Optimize some loops and double-map-lookups

* Optimize array instantiation

There are two styles to convert a collection to an array: either
using a pre-sized array (like c.toArray(new String[c.size()])) or
using an empty array (like c.toArray(new String[0]).

In older Java versions using pre-sized array was recommended,
as the reflection call which is necessary to create an array
of proper size was quite slow. However since late updates of
OpenJDK 6 this call was intrinsified, making the performance
of the empty array version the same and sometimes even better,
compared to the pre-sized version. Also passing pre-sized array
is dangerous for a concurrent or synchronized collection as
a data race is possible between the size and toArray call
which may result in extra nulls at the end of the array,
if the collection was concurrently shrunk during the operation.

* Cleanup string concatenation

* Use EnumMap where possible

* Use FastMath instead of Math

* Initialize complex things only once

* Reduce method size to aloow more JIT inlining

* remove map of short->float

* Move field to local variable

* Cleanup Map lookup

Co-authored-by: Rob Ekl <xwq876@zebra.com>
This commit is contained in:
robekl
2020-04-25 07:57:56 -04:00
committed by GitHub
parent 649258bd2b
commit 39f6d6c831
186 changed files with 2840 additions and 3464 deletions

View File

@@ -311,11 +311,11 @@ public class MixerManager
for(Mixer.Info mixerInfo : AudioSystem.getMixerInfo())
{
sb.append("\n--------------------------------------------------");
sb.append("\nMIXER name:" + mixerInfo.getName() +
"\n desc:" + mixerInfo.getDescription() +
"\n vendor:" + mixerInfo.getVendor() +
"\n version:" + mixerInfo.getVersion() +
"\n");
sb.append("\nMIXER name:").append(mixerInfo.getName())
.append("\n desc:").append(mixerInfo.getDescription())
.append("\n vendor:").append(mixerInfo.getVendor())
.append("\n version:").append(mixerInfo.getVersion())
.append("\n");
Mixer mixer = AudioSystem.getMixer(mixerInfo);
@@ -323,20 +323,20 @@ public class MixerManager
for(Line.Info lineInfo : sourceLines)
{
sb.append(" SOURCE LINE desc:" + lineInfo.toString() +
"\n class:" + lineInfo.getClass() +
"\n lineclass:" + lineInfo.getLineClass() +
"\n");
sb.append(" SOURCE LINE desc:").append(lineInfo)
.append("\n class:").append(lineInfo.getClass())
.append("\n lineclass:").append(lineInfo.getLineClass())
.append("\n");
}
Line.Info[] targetLines = mixer.getTargetLineInfo();
for(Line.Info lineInfo : targetLines)
{
sb.append(" TARGET LINE desc:" + lineInfo.toString() +
"\n class:" + lineInfo.getClass() +
"\n lineclass:" + lineInfo.getLineClass() +
"\n");
sb.append(" TARGET LINE desc:").append(lineInfo)
.append("\n class:").append(lineInfo.getClass())
.append("\n lineclass:").append(lineInfo.getLineClass())
.append("\n");
}
Line.Info portInfo = new Line.Info(Port.class);

View File

@@ -64,7 +64,7 @@ public class MixerSourceEditor extends Editor<Channel>
EnumSet<MixerChannel> channels = selected.getChannels();
mComboChannels.setModel(new DefaultComboBoxModel<MixerChannel>(
channels.toArray(new MixerChannel[channels.size()])));
channels.toArray(new MixerChannel[0])));
repaint();
@@ -84,7 +84,7 @@ public class MixerSourceEditor extends Editor<Channel>
EnumSet<MixerChannel> channels = selected.getChannels();
mComboChannels.setModel(new DefaultComboBoxModel<MixerChannel>(
channels.toArray(new MixerChannel[channels.size()])));
channels.toArray(new MixerChannel[0])));
}
mComboChannels.setEnabled(false);

View File

@@ -81,11 +81,11 @@ public class SystemMixerDevices {
for( Mixer.Info mixerInfo: AudioSystem.getMixerInfo() )
{
sb.append( "\n--------------------------------------------------" );
sb.append( "\nMIXER name:" + mixerInfo.getName() +
"\n desc:" + mixerInfo.getDescription() +
"\n vendor:" + mixerInfo.getVendor() +
"\n version:" + mixerInfo.getVersion() +
"\n" );
sb.append("\nMIXER name:").append(mixerInfo.getName())
.append("\n desc:").append(mixerInfo.getDescription())
.append("\n vendor:").append(mixerInfo.getVendor())
.append("\n version:").append(mixerInfo.getVersion())
.append("\n");
Mixer mixer = AudioSystem.getMixer( mixerInfo );
@@ -93,20 +93,20 @@ public class SystemMixerDevices {
for( Line.Info lineInfo: sourceLines )
{
sb.append( " SOURCE LINE desc:" + lineInfo.toString() +
"\n class:" + lineInfo.getClass() +
"\n lineclass:" + lineInfo.getLineClass() +
"\n" );
sb.append(" SOURCE LINE desc:").append(lineInfo)
.append("\n class:").append(lineInfo.getClass())
.append("\n lineclass:").append(lineInfo.getLineClass())
.append("\n");
}
Line.Info[] targetLines = mixer.getTargetLineInfo();
for( Line.Info lineInfo: targetLines )
{
sb.append( " TARGET LINE desc:" + lineInfo.toString() +
"\n class:" + lineInfo.getClass() +
"\n lineclass:" + lineInfo.getLineClass() +
"\n" );
sb.append(" TARGET LINE desc:").append(lineInfo)
.append("\n class:").append(lineInfo.getClass())
.append("\n lineclass:").append(lineInfo.getLineClass())
.append("\n");
}
}

View File

@@ -173,7 +173,7 @@ public class TunerManager
{
sb.append(" NOT LOADED: ");
sb.append(status.getInfo());
sb.append(" Error:" + e.getMessage());
sb.append(" Error:").append(e.getMessage());
}
}
else

View File

@@ -69,7 +69,7 @@ public class TunerSourceEditor extends Editor<Channel>
});
add(mFrequencyControl);
mTunerNameComboBox = new JComboBox<>(mCurrentTunerNames.toArray(new String[mCurrentTunerNames.size()]));
mTunerNameComboBox = new JComboBox<>(mCurrentTunerNames.toArray(new String[0]));
mTunerNameComboBox.addActionListener(new ActionListener()
{
@Override
@@ -103,13 +103,13 @@ public class TunerSourceEditor extends Editor<Channel>
List<String> updatedTunerNameList = new ArrayList<>(mCurrentTunerNames);
String unavailableTuner = preferredTuner + UNAVAILABLE_TUNER;
updatedTunerNameList.add(unavailableTuner);
String[] tunerNameArray = updatedTunerNameList.toArray(new String[updatedTunerNameList.size()]);
String[] tunerNameArray = updatedTunerNameList.toArray(new String[0]);
mTunerNameComboBox.setModel(new DefaultComboBoxModel<>(tunerNameArray));
mTunerNameComboBox.setSelectedItem(unavailableTuner);
}
else
{
String[] tunerNameArray = mCurrentTunerNames.toArray(new String[mCurrentTunerNames.size()]);
String[] tunerNameArray = mCurrentTunerNames.toArray(new String[0]);
mTunerNameComboBox.setModel(new DefaultComboBoxModel<>(tunerNameArray));
if(preferredTuner == null)

View File

@@ -71,7 +71,7 @@ public class TunerSourceMultipleFrequencyEditor extends Editor<Channel>
// mFrequencyEditor.setSize(new Dimension(100, 30));
add(mFrequencyEditor, "span 2 2");
mTunerNameComboBox = new JComboBox<>(mCurrentTunerNames.toArray(new String[mCurrentTunerNames.size()]));
mTunerNameComboBox = new JComboBox<>(mCurrentTunerNames.toArray(new String[0]));
mTunerNameComboBox.addActionListener(new ActionListener()
{
@Override
@@ -105,13 +105,13 @@ public class TunerSourceMultipleFrequencyEditor extends Editor<Channel>
List<String> updatedTunerNameList = new ArrayList<>(mCurrentTunerNames);
String unavailableTuner = preferredTuner + UNAVAILABLE_TUNER;
updatedTunerNameList.add(unavailableTuner);
String[] tunerNameArray = updatedTunerNameList.toArray(new String[updatedTunerNameList.size()]);
String[] tunerNameArray = updatedTunerNameList.toArray(new String[0]);
mTunerNameComboBox.setModel(new DefaultComboBoxModel<>(tunerNameArray));
mTunerNameComboBox.setSelectedItem(unavailableTuner);
}
else
{
String[] tunerNameArray = mCurrentTunerNames.toArray(new String[mCurrentTunerNames.size()]);
String[] tunerNameArray = mCurrentTunerNames.toArray(new String[0]);
mTunerNameComboBox.setModel(new DefaultComboBoxModel<>(tunerNameArray));
if(preferredTuner == null)

View File

@@ -150,7 +150,7 @@ public class AirspyTunerEditor extends TunerConfigurationEditor
mSampleRateCombo = new JComboBox<AirspySampleRate>(
new DefaultComboBoxModel<AirspySampleRate>(rates.toArray(
new AirspySampleRate[rates.size()])));
new AirspySampleRate[0])));
mSampleRateCombo.setEnabled(false);
mSampleRateCombo.addActionListener(new ActionListener()
{

View File

@@ -125,7 +125,7 @@ public class HackRFTunerEditor extends TunerConfigurationEditor
HackRFSampleRate[] validRates = HackRFSampleRate.VALID_SAMPLE_RATES
.toArray(new HackRFSampleRate[HackRFSampleRate.VALID_SAMPLE_RATES.size()]);
.toArray(new HackRFSampleRate[0]);
mComboSampleRate = new JComboBox<>(validRates);
mComboSampleRate.setEnabled(false);
mComboSampleRate.addActionListener(new ActionListener()

View File

@@ -28,6 +28,7 @@ import io.github.dsheirer.source.tuner.TunerController;
import io.github.dsheirer.source.tuner.channel.ChannelSpecification;
import io.github.dsheirer.source.tuner.channel.TunerChannel;
import io.github.dsheirer.source.tuner.channel.TunerChannelSource;
import org.apache.commons.math3.util.FastMath;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -215,7 +216,7 @@ public class PolyphaseChannelSourceManager extends ChannelSourceManager
//Align the test frequency to the next greater integral frequency placing the first channel at the
// minimum extreme of the available bandwidth as a starting location
double delta = Math.abs(startFrequency - bestIntegralFrequency);
double delta = FastMath.abs(startFrequency - bestIntegralFrequency);
double adjustment = delta % mPolyphaseChannelManager.getChannelBandwidth();
startFrequency += adjustment;
@@ -329,7 +330,7 @@ public class PolyphaseChannelSourceManager extends ChannelSourceManager
*/
private boolean isIntegralSpacing(long frequencyA, long frequencyB)
{
double delta = Math.abs(frequencyA - frequencyB);
double delta = FastMath.abs(frequencyA - frequencyB);
return delta % mPolyphaseChannelManager.getChannelBandwidth() <= 1.0;
}
@@ -364,7 +365,7 @@ public class PolyphaseChannelSourceManager extends ChannelSourceManager
{
if(firstChannel != secondChannel)
{
double delta = Math.abs(firstChannel.getFrequency() - secondChannel.getFrequency()) %
double delta = FastMath.abs(firstChannel.getFrequency() - secondChannel.getFrequency()) %
mPolyphaseChannelManager.getChannelBandwidth();
score += delta;

View File

@@ -22,6 +22,7 @@ import io.github.dsheirer.sample.buffer.ReusableBufferBroadcaster;
import io.github.dsheirer.sample.buffer.ReusableComplexBuffer;
import io.github.dsheirer.sample.buffer.ReusableComplexBufferQueue;
import io.github.dsheirer.util.ThreadPool;
import org.apache.commons.math3.util.FastMath;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -53,7 +54,7 @@ public class SampleGenerator
*/
public SampleGenerator(int sampleRate, long frequency, long interval, int sweepUpdateRate)
{
if(Math.abs(sweepUpdateRate) >= sampleRate)
if(FastMath.abs(sweepUpdateRate) >= sampleRate)
{
throw new IllegalArgumentException("Sweep update rate cannot be greater than sample rate");
}

View File

@@ -39,13 +39,11 @@ public class USBUtils
public static List<UsbDevice> getDevices()
throws SecurityException, UsbException, UnsupportedEncodingException
{
ArrayList<UsbDevice> devices = new ArrayList<UsbDevice>();
UsbServices services = UsbHostManager.getUsbServices();
UsbHub root = services.getRootUsbHub();
devices.addAll( getHubDevices( root ) );
ArrayList<UsbDevice> devices = new ArrayList<UsbDevice>(getHubDevices(root));
return devices;
}
@@ -60,20 +58,12 @@ public class USBUtils
@SuppressWarnings( "unchecked" )
List<UsbDevice> children = hub.getAttachedUsbDevices();
Iterator<UsbDevice> it = children.iterator();
while( it.hasNext() )
{
UsbDevice child = it.next();
if( child.isUsbHub() )
{
devices.addAll( getHubDevices( (UsbHub)child ) );
}
else
{
devices.add( child );
for (UsbDevice child : children) {
if (child.isUsbHub()) {
devices.addAll(getHubDevices((UsbHub) child));
} else {
devices.add(child);
}
}
@@ -85,25 +75,25 @@ public class USBUtils
{
StringBuilder sb = new StringBuilder();
sb.append( device.getUsbDeviceDescriptor().toString() + "\n\n" );
sb.append(device.getUsbDeviceDescriptor().toString()).append("\n\n");
for( Object configObject: device.getUsbConfigurations() )
{
UsbConfiguration config = (UsbConfiguration)configObject;
sb.append( config.getUsbConfigurationDescriptor().toString() + "\n\n" );
sb.append(config.getUsbConfigurationDescriptor().toString()).append("\n\n");
for( Object interfaceObject: config.getUsbInterfaces() )
{
UsbInterface iface = (UsbInterface)interfaceObject;
sb.append( iface.getUsbInterfaceDescriptor().toString() + "\n\n" );
sb.append(iface.getUsbInterfaceDescriptor().toString()).append("\n\n");
for( Object endpointObject: iface.getUsbEndpoints() )
{
UsbEndpoint endpoint = (UsbEndpoint)endpointObject;
sb.append( endpoint.getUsbEndpointDescriptor().toString() + "\n\n" );
sb.append(endpoint.getUsbEndpointDescriptor().toString()).append("\n\n");
}
}
}

View File

@@ -30,6 +30,7 @@ import io.github.dsheirer.source.IControllableFileSource;
import io.github.dsheirer.source.IFrameLocationListener;
import io.github.dsheirer.source.SourceEvent;
import io.github.dsheirer.util.ThreadPool;
import org.apache.commons.math3.util.FastMath;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -367,7 +368,7 @@ public class ComplexWaveSource extends ComplexSource implements IControllableFil
public void run()
{
mIntervals++;
int framesToRead = (int)Math.floor((mIntervals * mFramesPerInterval) - mFramesRead);
int framesToRead = (int) FastMath.floor((mIntervals * mFramesPerInterval) - mFramesRead);
try
{