Skip to main content
Code Review

Return to Question

replaced http://codereview.stackexchange.com/ with https://codereview.stackexchange.com/
Source Link

Created the follow-up question follow-up question as suggested.

Created the follow-up question as suggested.

Created the follow-up question as suggested.

added 208 characters in body
Source Link
StepTNT
  • 385
  • 1
  • 8
  • read files from a directory containing images
  • for each file, apply a [repetition code][1]repetition code (with n repetitions, user input)
  • for each file, send the result of the repetition code on a simulated channel with a given error probability. This means reading each bit and flipping it if we have an error
  • for each file, decode the file received from the channel and save it back as image

Any idea on how to speed things up while keeping a good readability? Considered that I need to work with 500+ images, wasting 8 minutes every 15 images leads to huge times. [1]

EDIT:

Created the https://en.wikipedia.org/wiki/Repetition_code follow-up question as suggested.

  • read files from a directory containing images
  • for each file, apply a [repetition code][1] (with n repetitions, user input)
  • for each file, send the result of the repetition code on a simulated channel with a given error probability. This means reading each bit and flipping it if we have an error
  • for each file, decode the file received from the channel and save it back as image

Any idea on how to speed things up while keeping a good readability? Considered that I need to work with 500+ images, wasting 8 minutes every 15 images leads to huge times. [1]: https://en.wikipedia.org/wiki/Repetition_code

  • read files from a directory containing images
  • for each file, apply a repetition code (with n repetitions, user input)
  • for each file, send the result of the repetition code on a simulated channel with a given error probability. This means reading each bit and flipping it if we have an error
  • for each file, decode the file received from the channel and save it back as image

Any idea on how to speed things up while keeping a good readability? Considered that I need to work with 500+ images, wasting 8 minutes every 15 images leads to huge times.

EDIT:

Created the follow-up question as suggested.

Rollback to Revision 1
Source Link
IEatBagels
  • 12.6k
  • 3
  • 48
  • 99

EDIT: I removed the old code and added the new one so be sure to check it out if you want to help me.

  • read files from a directory containing images
  • for each file, apply a repetition code [repetition code][1] (with n repetitions, user input)
  • for each file, send the result of the repetition code on a simulated channel with a given error probability. This means reading each bit and flipping it if we have an error
  • for each file, decode the file received from the channel and save it back as image

EDIT: The BitStream class is from org.icepdf.core.io package, feel free to suggest a better alternative if you wish!TestLoop

for (int i = 0; i < 15; i++) {
 byte[] input = Files.readAllBytes(new File("D:\\testFrame.jpg").toPath());
 String inputString = Converter.byteArrayToBitString(input);
 int repetitions = 5, coefficient = 10, exponent = -3;
 // Repetitions (encoding)
 RepetitionCoder coder = RepetitionFactory.createRepetitionCoder(repetitions);
 String repCoderOutput = coder.encode(inputString);
 // Noisy channel
 BaseError error = ErrorFactory.createError(coefficient, exponent);
 NoisyChannel channel = new NoisyChannel(error);
 String channelOutput = channel.transfer(repCoderOutput);
 // Repetitions (decoding)
 RepetitionDecoder decoder = RepetitionFactory.createRepetitionDecoder(repetitions);
 String repDecoderOutput = decoder.decode(channelOutput);
 byte[] output = Converter.bitStringToByteArray(repDecoderOutput);
 Files.write(new File("D:\\testFrame_2.jpg").toPath(), output);
}

TestLoopConverter.byteArrayToBitString

for (int i = 0; i < 15; i++) {
 byte[] input = Files.readAllBytes(new File("D:\\testFrame.jpg").toPath());
 ByteArrayInputStream bis = new ByteArrayInputStream(input);
 ByteArrayOutputStream bos = new ByteArrayOutputStream();
 // Repetition coder
 RepetitionCoder repCoder = RepetitionFactory.createRepetitionCoder(5);
 repCoder.encode(newpublic BitStream(bis),static newString BitStreambyteArrayToBitString(bos));
 bis = newbyte[] ByteArrayInputStream(bos.toByteArray()source);
  bos.reset();{
 NoisyChannelStringBuilder channelsb = new NoisyChannel(ErrorFactory.createErrorStringBuilder(10, -3, 0));
 8 * channelsource.transfer(new BitStream(bis), new BitStream(bos)length);
 bis = newfor ByteArrayInputStream(bos.toByteArray());
 byte b : bos.reset(source);
 // Repetition decoder{
 RepetitionDecoder repDecoder = RepetitionFactory.createRepetitionDecoder(5);
  repDecodersb.decode(new BitStreamappend(bis), new BitStreambyteToBitString(bosb));
 // Write}
 Files.write(outputFile.toPath(),return bossb.toByteArraytoString());
}
public voidString encode(BitStream in, BitStreamString outbitString){
 tryreturn {repeat(bitString);
}
private whileString (in.availablerepeat() >String 0bitString) {
 // Read one bit
 intStringBuilder currentBitsb = innew StringBuilder(bitString.getBitslength(1);
  // Output that bit* repetitions times);
 for (int i = 0; ichar <c repetitions;: i++bitString.toCharArray()) {
 char[] chars = new out.putBit(currentBit);char[repetitions];
 Arrays.fill(chars, }c);
 }
 } catch sb.append(IOException exchars) {;
 }
 LOG.log(Level.SEVERE,return exsb.getMessagetoString(), ex);
 }
}
public voidString transfer(BitStreamString input, BitStream output) throws IOException {
 whilechar[] (bits = input.availabletoCharArray() > 0) {
 // Read one bit;
 for (int biti = input.getBits(1);
 0; i < //bits.length; Applyi++) error{
 int errorBitbits[i] = errorModel.addError(bitbits[i]);
 // Output the altered bit}
 return new output.putBitString(errorBitbits);
 }
}
protected intchar addError(intchar source) {
 ifreturn (isError()) {
 // Flip the bit
  return? flipBit(source == 0) ? 1 : 0;
 }
  return source;
}
protected boolean isError() {
 for (int i = 0; i < Math.abs(exponent); i++) {
 if (Math.random() >= 0.1) {
 return false;
 }
 }
 return !(coefficient > 0 && Math.random() >= coefficient / 10);
}
protected char flipBit(char bit) {
 return (bit == '0') ? (char) 49 : (char) 48;
}
public voidString decode(BitStreamString in,bitString) BitStream{
 out) throws IOException {String[] repetitionsString = splitStringEvery(bitString, repetitions);
 whileStringBuilder sb = new StringBuilder(inrepetitionsString.available(length);
 > 0 for (String rep : repetitionsString) {
 intsb.append(majorityVote(rep));
 zeroes = 0; }
 return sb.toString();
}
private String[] splitStringEvery(String //s, Readint repetitionsinterval) times{
 and count zeroes int arrayLength = (int) Math.ceil(((s.length() / (double) interval)));
 String[] result = new forString[arrayLength];
 (int ij = 0; i < repetitions; i++)int {
lastIndex = result.length - 1;
 for (int i = if0; (in.getBits(1)i ==< 0lastIndex; i++) {
 result[i] = s.substring(j, j + interval);
 zeroes += 1;
 j += interval;
 }
 }
 result[lastIndex] = s.substring(j);
 return result;
}
private char majorityVote(String buffer) {
 //int Outputzeroes 0= if(int) zeroesbuffer.chars().filter(b -> repetitions/2,b 1== otherwise48).count();
 return out.putBit((zeroes > repetitions / 2) ? 0'0' : 1);
  }'1';
}

Any idea on how to speed things up while keeping a good readability?Converter.bitStringToByteArray

public static byte[] bitStringToByteArray(String string) {
 byte[] result = new byte[string.length() / 8];
 for (int i = 0; i < string.length(); i += 8) {
 String subString = string.substring(i, i + 8);
 result[i / 8] = bitStringToByte(subString);
 }
 return result;
}

EDITAny idea on how to speed things up while keeping a good readability? Considered that I need to work with 500+ images, wasting 8 minutes every 15 images leads to huge times. [1]: code now is way faster (almost 8 times), but it still feels slow because it does 15 images per minute (0.25 fps) and I think there's still room for improvement.https://en.wikipedia.org/wiki/Repetition_code

EDIT: I removed the old code and added the new one so be sure to check it out if you want to help me.

  • read files from a directory containing images
  • for each file, apply a repetition code (with n repetitions, user input)
  • for each file, send the result of the repetition code on a simulated channel with a given error probability. This means reading each bit and flipping it if we have an error
  • for each file, decode the file received from the channel and save it back as image

EDIT: The BitStream class is from org.icepdf.core.io package, feel free to suggest a better alternative if you wish!

TestLoop

for (int i = 0; i < 15; i++) {
 byte[] input = Files.readAllBytes(new File("D:\\testFrame.jpg").toPath());
 ByteArrayInputStream bis = new ByteArrayInputStream(input);
 ByteArrayOutputStream bos = new ByteArrayOutputStream();
 // Repetition coder
 RepetitionCoder repCoder = RepetitionFactory.createRepetitionCoder(5);
 repCoder.encode(new BitStream(bis), new BitStream(bos));
 bis = new ByteArrayInputStream(bos.toByteArray());
  bos.reset();
 NoisyChannel channel = new NoisyChannel(ErrorFactory.createError(10, -3, 0));
  channel.transfer(new BitStream(bis), new BitStream(bos));
 bis = new ByteArrayInputStream(bos.toByteArray());
  bos.reset();
 // Repetition decoder
 RepetitionDecoder repDecoder = RepetitionFactory.createRepetitionDecoder(5);
  repDecoder.decode(new BitStream(bis), new BitStream(bos));
 // Write
 Files.write(outputFile.toPath(), bos.toByteArray());
}
public void encode(BitStream in, BitStream out){
 try {
 while (in.available() > 0) {
 // Read one bit
 int currentBit = in.getBits(1);
  // Output that bit repetitions times
 for (int i = 0; i < repetitions; i++) {
 out.putBit(currentBit);
 }
 }
 } catch (IOException ex) {
 LOG.log(Level.SEVERE, ex.getMessage(), ex);
 }
}
public void transfer(BitStream input, BitStream output) throws IOException {
 while (input.available() > 0) {
 // Read one bit
 int bit = input.getBits(1);
  // Apply error
 int errorBit = errorModel.addError(bit);
 // Output the altered bit
 output.putBit(errorBit);
 }
}
protected int addError(int source) {
 if (isError()) {
 // Flip the bit
  return (source == 0) ? 1 : 0;
 }
  return source;
}
protected boolean isError() {
 for (int i = 0; i < Math.abs(exponent); i++) {
 if (Math.random() >= 0.1) {
 return false;
 }
 }
 return !(coefficient > 0 && Math.random() >= coefficient / 10);
}
public void decode(BitStream in, BitStream out) throws IOException {
 while (in.available() > 0) {
 int zeroes = 0;
 // Read repetitions times and count zeroes
 for (int i = 0; i < repetitions; i++) {
 if (in.getBits(1) == 0) {
 zeroes += 1;
 }
 }
 // Output 0 if zeroes > repetitions/2, 1 otherwise
 out.putBit((zeroes > repetitions / 2) ? 0 : 1);
  }
}

Any idea on how to speed things up while keeping a good readability?

EDIT: code now is way faster (almost 8 times), but it still feels slow because it does 15 images per minute (0.25 fps) and I think there's still room for improvement.

  • read files from a directory containing images
  • for each file, apply a [repetition code][1] (with n repetitions, user input)
  • for each file, send the result of the repetition code on a simulated channel with a given error probability. This means reading each bit and flipping it if we have an error
  • for each file, decode the file received from the channel and save it back as image

TestLoop

for (int i = 0; i < 15; i++) {
 byte[] input = Files.readAllBytes(new File("D:\\testFrame.jpg").toPath());
 String inputString = Converter.byteArrayToBitString(input);
 int repetitions = 5, coefficient = 10, exponent = -3;
 // Repetitions (encoding)
 RepetitionCoder coder = RepetitionFactory.createRepetitionCoder(repetitions);
 String repCoderOutput = coder.encode(inputString);
 // Noisy channel
 BaseError error = ErrorFactory.createError(coefficient, exponent);
 NoisyChannel channel = new NoisyChannel(error);
 String channelOutput = channel.transfer(repCoderOutput);
 // Repetitions (decoding)
 RepetitionDecoder decoder = RepetitionFactory.createRepetitionDecoder(repetitions);
 String repDecoderOutput = decoder.decode(channelOutput);
 byte[] output = Converter.bitStringToByteArray(repDecoderOutput);
 Files.write(new File("D:\\testFrame_2.jpg").toPath(), output);
}

Converter.byteArrayToBitString

public static String byteArrayToBitString(byte[] source) {
 StringBuilder sb = new StringBuilder(8 * source.length);
 for (byte b : source) {
 sb.append(byteToBitString(b));
 }
 return sb.toString();
}
public String encode(String bitString){
 return repeat(bitString);
}
private String repeat(String bitString) {
 StringBuilder sb = new StringBuilder(bitString.length() * repetitions);
 for (char c : bitString.toCharArray()) {
 char[] chars = new char[repetitions];
 Arrays.fill(chars, c);
 sb.append(chars);
 }
 return sb.toString();
}
public String transfer(String input) {
 char[] bits = input.toCharArray();
 for (int i = 0; i < bits.length; i++) {
 bits[i] = errorModel.addError(bits[i]);
 }
 return new String(bits);
}
protected char addError(char source) {
 return (isError()) ? flipBit(source) : source;
}
protected boolean isError() {
 for (int i = 0; i < Math.abs(exponent); i++) {
 if (Math.random() >= 0.1) {
 return false;
 }
 }
 return !(coefficient > 0 && Math.random() >= coefficient / 10);
}
protected char flipBit(char bit) {
 return (bit == '0') ? (char) 49 : (char) 48;
}
public String decode(String bitString) {
 String[] repetitionsString = splitStringEvery(bitString, repetitions);
 StringBuilder sb = new StringBuilder(repetitionsString.length);
  for (String rep : repetitionsString) {
 sb.append(majorityVote(rep));
  }
 return sb.toString();
}
private String[] splitStringEvery(String s, int interval) {
  int arrayLength = (int) Math.ceil(((s.length() / (double) interval)));
 String[] result = new String[arrayLength];
 int j = 0; int lastIndex = result.length - 1;
 for (int i = 0; i < lastIndex; i++) {
 result[i] = s.substring(j, j + interval);
 j += interval;
 }
 result[lastIndex] = s.substring(j);
 return result;
}
private char majorityVote(String buffer) {
 int zeroes = (int) buffer.chars().filter(b -> b == 48).count();
 return (zeroes > repetitions / 2) ? '0' : '1';
}

Converter.bitStringToByteArray

public static byte[] bitStringToByteArray(String string) {
 byte[] result = new byte[string.length() / 8];
 for (int i = 0; i < string.length(); i += 8) {
 String subString = string.substring(i, i + 8);
 result[i / 8] = bitStringToByte(subString);
 }
 return result;
}

Any idea on how to speed things up while keeping a good readability? Considered that I need to work with 500+ images, wasting 8 minutes every 15 images leads to huge times. [1]: https://en.wikipedia.org/wiki/Repetition_code

Updated code with a new and faster version
Source Link
StepTNT
  • 385
  • 1
  • 8
Loading
Source Link
StepTNT
  • 385
  • 1
  • 8
Loading
lang-java

AltStyle によって変換されたページ (->オリジナル) /