Если вам просто нужно проверить, есть ли какие-либо элементы в массиве
if (empty($playerlist)) {
// list is empty.
}
Если вам нужно очистить пустые значения перед проверкой (обычно делается для предотвращения explode
странных строк):
foreach ($playerlist as $key => $value) {
if (empty($value)) {
unset($playerlist[$key]);
}
}
if (empty($playerlist)) {
//empty array
}
Спасибо за каждый ответ, но я уже нашел метод, соответствующий моим критериям:
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("./path"));
int n = readInt(bis);
int t = readInt(bis);
int array[] = new int[n];
for (int i = 0; i < n; i++) {
array[i] = readInt(bis);
}
private static int readInt(InputStream in) throws IOException {
int ret = 0;
boolean dig = false;
for (int c = 0; (c = in.read()) != -1; ) {
if (c >= '0' && c <= '9') {
dig = true;
ret = ret * 10 + c - '0';
} else if (dig) break;
}
return ret;
}
Для чтения 1 миллиона целых чисел требуется всего около 300 мс!
Можно переформатировать вход так, чтобы каждое целое было на отдельной строке (вместо одной длинной строки с миллионом целых чисел), вы должны видеть значительно улучшенную производительность, используя Integer.parseInt(BufferedReader.readLine())
из-за более умного буферизации по строке, а не чтобы разделить длинную строку на отдельный массив строк.
Edit: я протестировал это и смог прочитать результат, полученный seq 1 1000000
, в массив из int
в течение полусекунды, но конечно, это зависит от машины.
StreamTokenizer
может быть быстрее, как предлагается здесь .
Вы можете уменьшить время для результата StreamTokenizer
, используя BufferedReader
:
Reader r = null;
try {
r = new BufferedReader(new FileReader(file));
final StreamTokenizer st = new StreamTokenizer(r);
...
} finally {
if (r != null)
r.close();
}
Кроме того, не забудьте закрыть ваши файлы, как я показал здесь.
Вы также можете сэкономить время, используя пользовательский токенизатор для ваших целей:
public class CustomTokenizer {
private final Reader r;
public CustomTokenizer(final Reader r) {
this.r = r;
}
public int nextInt() throws IOException {
int i = r.read();
if (i == -1)
throw new EOFException();
char c = (char) i;
// Skip any whitespace
while (c == ' ' || c == '\n' || c == '\r') {
i = r.read();
if (i == -1)
throw new EOFException();
c = (char) i;
}
int result = (c - '0');
while ((i = r.read()) >= 0) {
c = (char) i;
if (c == ' ' || c == '\n' || c == '\r')
break;
result = result * 10 + (c - '0');
}
return result;
}
}
Не забудьте использовать для этого BufferedReader
. Этот пользовательский токенизатор предполагает, что входные данные всегда полностью действительны и содержат только пробелы, новые строки и цифры.
Если вы много читаете эти результаты, и эти результаты мало меняются, вы, вероятно, должны сохранить массив и следить за последним измененным временем файла. Затем, если файл не изменился, просто используйте кешированную копию массива, и это значительно ускорит результаты. Например:
public class ArrayRetriever {
private File inputFile;
private long lastModified;
private int[] lastResult;
public ArrayRetriever(File file) {
this.inputFile = file;
}
public int[] getResult() {
if (lastResult != null && inputFile.lastModified() == lastModified)
return lastResult;
lastModified = inputFile.lastModified();
// do logic to actually read the file here
lastResult = array; // the array variable from your examples
return lastResult;
}
}
BufferedReader
.
– trashgod
23 April 2010 в 03:57
Сколько памяти у вас на компьютере? Вы можете столкнуться с проблемами GC.
Самое лучшее, что нужно сделать, это обработать данные по одной строке за раз, если это возможно. Не загружайте его в массив. Загрузите то, что вам нужно, обработайте, запишите и продолжите.
Это уменьшит объем памяти и по-прежнему будет использовать то же количество файлов IO
int
обойдется мне в 7 МБ памяти - это не так много. Мне просто нужно загрузить эти данные из файла в память - мне понадобится это для некоторых вычислений, требующих загрузки целой информации.
– Crozin
22 April 2010 в 19:45
Я бы расширил FilterReader и проанализировал строку, поскольку она читается в методе read (). Попросите метод getNextNumber вернуть числа. Код оставлен как упражнение для читателя.
Использование StreamTokenizer на BufferedReader даст вам неплохую производительность. Вам не нужно писать собственную функцию readInt ().
Вот код, который я использовал для локального тестирования производительности:
/**
* Created by zhenhua.xu on 11/27/16.
*/
public class MyReader {
private static final String FILE_NAME = "./1m_numbers.txt";
private static final int n = 1000000;
public static void main(String[] args) {
try {
readByScanner();
readByStreamTokenizer();
readByStreamTokenizerOnBufferedReader();
readByBufferedInputStream();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void readByScanner() throws Exception {
long startTime = System.currentTimeMillis();
Scanner stdin = new Scanner(new File(FILE_NAME));
int array[] = new int[n];
for (int i = 0; i < n; i++) {
array[i] = stdin.nextInt();
}
long endTime = System.currentTimeMillis();
System.out.println(String.format("Total time by Scanner: %d ms", endTime - startTime));
}
public static void readByStreamTokenizer() throws Exception {
long startTime = System.currentTimeMillis();
StreamTokenizer st = new StreamTokenizer(new FileReader(FILE_NAME));
int array[] = new int[n];
for (int i = 0; st.nextToken() != StreamTokenizer.TT_EOF; i++) {
array[i] = (int) st.nval;
}
long endTime = System.currentTimeMillis();
System.out.println(String.format("Total time by StreamTokenizer: %d ms", endTime - startTime));
}
public static void readByStreamTokenizerOnBufferedReader() throws Exception {
long startTime = System.currentTimeMillis();
StreamTokenizer st = new StreamTokenizer(new BufferedReader(new FileReader(FILE_NAME)));
int array[] = new int[n];
for (int i = 0; st.nextToken() != StreamTokenizer.TT_EOF; i++) {
array[i] = (int) st.nval;
}
long endTime = System.currentTimeMillis();
System.out.println(String.format("Total time by StreamTokenizer with BufferedReader: %d ms", endTime - startTime));
}
public static void readByBufferedInputStream() throws Exception {
long startTime = System.currentTimeMillis();
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(FILE_NAME));
int array[] = new int[n];
for (int i = 0; i < n; i++) {
array[i] = readInt(bis);
}
long endTime = System.currentTimeMillis();
System.out.println(String.format("Total time with BufferedInputStream: %d ms", endTime - startTime));
}
private static int readInt(InputStream in) throws IOException {
int ret = 0;
boolean dig = false;
for (int c = 0; (c = in.read()) != -1; ) {
if (c >= '0' && c <= '9') {
dig = true;
ret = ret * 10 + c - '0';
} else if (dig) break;
}
return ret;
}
Результаты, которые я получил:
int t
? – Adam Johns 27 June 2014 в 16:48array
также ничего не делает. ;) – Crozin 28 June 2014 в 07:36StringTokenizer
в моей проблеме (чтение 1 миллион целых чисел до 1 миллиона каждый). – jbarrameda 28 February 2017 в 23:26